1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * BMP image format decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2005 Mans Rullgard 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <inttypes.h> 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "avcodec.h" 25cabdff1aSopenharmony_ci#include "bytestream.h" 26cabdff1aSopenharmony_ci#include "bmp.h" 27cabdff1aSopenharmony_ci#include "codec_internal.h" 28cabdff1aSopenharmony_ci#include "internal.h" 29cabdff1aSopenharmony_ci#include "msrledec.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_cistatic int bmp_decode_frame(AVCodecContext *avctx, AVFrame *p, 32cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 33cabdff1aSopenharmony_ci{ 34cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 35cabdff1aSopenharmony_ci int buf_size = avpkt->size; 36cabdff1aSopenharmony_ci unsigned int fsize, hsize; 37cabdff1aSopenharmony_ci int width, height; 38cabdff1aSopenharmony_ci unsigned int depth; 39cabdff1aSopenharmony_ci BiCompression comp; 40cabdff1aSopenharmony_ci unsigned int ihsize; 41cabdff1aSopenharmony_ci int i, j, n, linesize, ret; 42cabdff1aSopenharmony_ci uint32_t rgb[3] = {0}; 43cabdff1aSopenharmony_ci uint32_t alpha = 0; 44cabdff1aSopenharmony_ci uint8_t *ptr; 45cabdff1aSopenharmony_ci int dsize; 46cabdff1aSopenharmony_ci const uint8_t *buf0 = buf; 47cabdff1aSopenharmony_ci GetByteContext gb; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci if (buf_size < 14) { 50cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); 51cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 52cabdff1aSopenharmony_ci } 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci if (bytestream_get_byte(&buf) != 'B' || 55cabdff1aSopenharmony_ci bytestream_get_byte(&buf) != 'M') { 56cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); 57cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 58cabdff1aSopenharmony_ci } 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci fsize = bytestream_get_le32(&buf); 61cabdff1aSopenharmony_ci if (buf_size < fsize) { 62cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %u), trying to decode anyway\n", 63cabdff1aSopenharmony_ci buf_size, fsize); 64cabdff1aSopenharmony_ci fsize = buf_size; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci buf += 2; /* reserved1 */ 68cabdff1aSopenharmony_ci buf += 2; /* reserved2 */ 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci hsize = bytestream_get_le32(&buf); /* header size */ 71cabdff1aSopenharmony_ci ihsize = bytestream_get_le32(&buf); /* more header size */ 72cabdff1aSopenharmony_ci if (ihsize + 14LL > hsize) { 73cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid header size %u\n", hsize); 74cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 75cabdff1aSopenharmony_ci } 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci /* sometimes file size is set to some headers size, set a real size in that case */ 78cabdff1aSopenharmony_ci if (fsize == 14 || fsize == ihsize + 14) 79cabdff1aSopenharmony_ci fsize = buf_size - 2; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci if (fsize <= hsize) { 82cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 83cabdff1aSopenharmony_ci "Declared file size is less than header size (%u < %u)\n", 84cabdff1aSopenharmony_ci fsize, hsize); 85cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci switch (ihsize) { 89cabdff1aSopenharmony_ci case 40: // windib 90cabdff1aSopenharmony_ci case 56: // windib v3 91cabdff1aSopenharmony_ci case 64: // OS/2 v2 92cabdff1aSopenharmony_ci case 108: // windib v4 93cabdff1aSopenharmony_ci case 124: // windib v5 94cabdff1aSopenharmony_ci width = bytestream_get_le32(&buf); 95cabdff1aSopenharmony_ci height = bytestream_get_le32(&buf); 96cabdff1aSopenharmony_ci break; 97cabdff1aSopenharmony_ci case 12: // OS/2 v1 98cabdff1aSopenharmony_ci width = bytestream_get_le16(&buf); 99cabdff1aSopenharmony_ci height = bytestream_get_le16(&buf); 100cabdff1aSopenharmony_ci break; 101cabdff1aSopenharmony_ci default: 102cabdff1aSopenharmony_ci avpriv_report_missing_feature(avctx, "Information header size %u", 103cabdff1aSopenharmony_ci ihsize); 104cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 105cabdff1aSopenharmony_ci } 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci /* planes */ 108cabdff1aSopenharmony_ci if (bytestream_get_le16(&buf) != 1) { 109cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); 110cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 111cabdff1aSopenharmony_ci } 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci depth = bytestream_get_le16(&buf); 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci if (ihsize >= 40) 116cabdff1aSopenharmony_ci comp = bytestream_get_le32(&buf); 117cabdff1aSopenharmony_ci else 118cabdff1aSopenharmony_ci comp = BMP_RGB; 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && 121cabdff1aSopenharmony_ci comp != BMP_RLE8) { 122cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); 123cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci if (comp == BMP_BITFIELDS) { 127cabdff1aSopenharmony_ci buf += 20; 128cabdff1aSopenharmony_ci rgb[0] = bytestream_get_le32(&buf); 129cabdff1aSopenharmony_ci rgb[1] = bytestream_get_le32(&buf); 130cabdff1aSopenharmony_ci rgb[2] = bytestream_get_le32(&buf); 131cabdff1aSopenharmony_ci if (ihsize > 40) 132cabdff1aSopenharmony_ci alpha = bytestream_get_le32(&buf); 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci ret = ff_set_dimensions(avctx, width, height > 0 ? height : -(unsigned)height); 136cabdff1aSopenharmony_ci if (ret < 0) { 137cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions %d %d\n", width, height); 138cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 139cabdff1aSopenharmony_ci } 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_NONE; 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci switch (depth) { 144cabdff1aSopenharmony_ci case 32: 145cabdff1aSopenharmony_ci if (comp == BMP_BITFIELDS) { 146cabdff1aSopenharmony_ci if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00) 147cabdff1aSopenharmony_ci avctx->pix_fmt = alpha ? AV_PIX_FMT_ABGR : AV_PIX_FMT_0BGR; 148cabdff1aSopenharmony_ci else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF) 149cabdff1aSopenharmony_ci avctx->pix_fmt = alpha ? AV_PIX_FMT_BGRA : AV_PIX_FMT_BGR0; 150cabdff1aSopenharmony_ci else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000) 151cabdff1aSopenharmony_ci avctx->pix_fmt = alpha ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB; 152cabdff1aSopenharmony_ci else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000) 153cabdff1aSopenharmony_ci avctx->pix_fmt = alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB0; 154cabdff1aSopenharmony_ci else { 155cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unknown bitfields " 156cabdff1aSopenharmony_ci "%0"PRIX32" %0"PRIX32" %0"PRIX32"\n", rgb[0], rgb[1], rgb[2]); 157cabdff1aSopenharmony_ci return AVERROR(EINVAL); 158cabdff1aSopenharmony_ci } 159cabdff1aSopenharmony_ci } else { 160cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_BGRA; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci break; 163cabdff1aSopenharmony_ci case 24: 164cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_BGR24; 165cabdff1aSopenharmony_ci break; 166cabdff1aSopenharmony_ci case 16: 167cabdff1aSopenharmony_ci if (comp == BMP_RGB) 168cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_RGB555; 169cabdff1aSopenharmony_ci else if (comp == BMP_BITFIELDS) { 170cabdff1aSopenharmony_ci if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F) 171cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_RGB565; 172cabdff1aSopenharmony_ci else if (rgb[0] == 0x7C00 && rgb[1] == 0x03E0 && rgb[2] == 0x001F) 173cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_RGB555; 174cabdff1aSopenharmony_ci else if (rgb[0] == 0x0F00 && rgb[1] == 0x00F0 && rgb[2] == 0x000F) 175cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_RGB444; 176cabdff1aSopenharmony_ci else { 177cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 178cabdff1aSopenharmony_ci "Unknown bitfields %0"PRIX32" %0"PRIX32" %0"PRIX32"\n", 179cabdff1aSopenharmony_ci rgb[0], rgb[1], rgb[2]); 180cabdff1aSopenharmony_ci return AVERROR(EINVAL); 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci break; 184cabdff1aSopenharmony_ci case 8: 185cabdff1aSopenharmony_ci if (hsize - ihsize - 14 > 0) 186cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_PAL8; 187cabdff1aSopenharmony_ci else 188cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_GRAY8; 189cabdff1aSopenharmony_ci break; 190cabdff1aSopenharmony_ci case 1: 191cabdff1aSopenharmony_ci case 4: 192cabdff1aSopenharmony_ci if (hsize - ihsize - 14 > 0) { 193cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_PAL8; 194cabdff1aSopenharmony_ci } else { 195cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unknown palette for %u-colour BMP\n", 196cabdff1aSopenharmony_ci 1 << depth); 197cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci break; 200cabdff1aSopenharmony_ci default: 201cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "depth %u not supported\n", depth); 202cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_NONE) { 206cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); 207cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 208cabdff1aSopenharmony_ci } 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 211cabdff1aSopenharmony_ci return ret; 212cabdff1aSopenharmony_ci p->pict_type = AV_PICTURE_TYPE_I; 213cabdff1aSopenharmony_ci p->key_frame = 1; 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci buf = buf0 + hsize; 216cabdff1aSopenharmony_ci dsize = buf_size - hsize; 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci /* Line size in file multiple of 4 */ 219cabdff1aSopenharmony_ci n = ((avctx->width * depth + 31) / 8) & ~3; 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) { 222cabdff1aSopenharmony_ci n = (avctx->width * depth + 7) / 8; 223cabdff1aSopenharmony_ci if (n * avctx->height > dsize) { 224cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", 225cabdff1aSopenharmony_ci dsize, n * avctx->height); 226cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 227cabdff1aSopenharmony_ci } 228cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "data size too small, assuming missing line alignment\n"); 229cabdff1aSopenharmony_ci } 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci // RLE may skip decoding some picture areas, so blank picture before decoding 232cabdff1aSopenharmony_ci if (comp == BMP_RLE4 || comp == BMP_RLE8) 233cabdff1aSopenharmony_ci memset(p->data[0], 0, avctx->height * p->linesize[0]); 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci if (height > 0) { 236cabdff1aSopenharmony_ci ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; 237cabdff1aSopenharmony_ci linesize = -p->linesize[0]; 238cabdff1aSopenharmony_ci } else { 239cabdff1aSopenharmony_ci ptr = p->data[0]; 240cabdff1aSopenharmony_ci linesize = p->linesize[0]; 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 244cabdff1aSopenharmony_ci int colors = 1 << depth; 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci memset(p->data[1], 0, 1024); 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci if (ihsize >= 36) { 249cabdff1aSopenharmony_ci int t; 250cabdff1aSopenharmony_ci buf = buf0 + 46; 251cabdff1aSopenharmony_ci t = bytestream_get_le32(&buf); 252cabdff1aSopenharmony_ci if (t < 0 || t > (1 << depth)) { 253cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 254cabdff1aSopenharmony_ci "Incorrect number of colors - %X for bitdepth %u\n", 255cabdff1aSopenharmony_ci t, depth); 256cabdff1aSopenharmony_ci } else if (t) { 257cabdff1aSopenharmony_ci colors = t; 258cabdff1aSopenharmony_ci } 259cabdff1aSopenharmony_ci } else { 260cabdff1aSopenharmony_ci colors = FFMIN(256, (hsize-ihsize-14) / 3); 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci buf = buf0 + 14 + ihsize; //palette location 263cabdff1aSopenharmony_ci // OS/2 bitmap, 3 bytes per palette entry 264cabdff1aSopenharmony_ci if ((hsize-ihsize-14) < (colors << 2)) { 265cabdff1aSopenharmony_ci if ((hsize-ihsize-14) < colors * 3) { 266cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "palette doesn't fit in packet\n"); 267cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 268cabdff1aSopenharmony_ci } 269cabdff1aSopenharmony_ci for (i = 0; i < colors; i++) 270cabdff1aSopenharmony_ci ((uint32_t*)p->data[1])[i] = (0xFFU<<24) | bytestream_get_le24(&buf); 271cabdff1aSopenharmony_ci } else { 272cabdff1aSopenharmony_ci for (i = 0; i < colors; i++) 273cabdff1aSopenharmony_ci ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf); 274cabdff1aSopenharmony_ci } 275cabdff1aSopenharmony_ci buf = buf0 + hsize; 276cabdff1aSopenharmony_ci } 277cabdff1aSopenharmony_ci if (comp == BMP_RLE4 || comp == BMP_RLE8) { 278cabdff1aSopenharmony_ci if (comp == BMP_RLE8 && height < 0) { 279cabdff1aSopenharmony_ci p->data[0] += p->linesize[0] * (avctx->height - 1); 280cabdff1aSopenharmony_ci p->linesize[0] = -p->linesize[0]; 281cabdff1aSopenharmony_ci } 282cabdff1aSopenharmony_ci bytestream2_init(&gb, buf, dsize); 283cabdff1aSopenharmony_ci ff_msrle_decode(avctx, p, depth, &gb); 284cabdff1aSopenharmony_ci if (height < 0) { 285cabdff1aSopenharmony_ci p->data[0] += p->linesize[0] * (avctx->height - 1); 286cabdff1aSopenharmony_ci p->linesize[0] = -p->linesize[0]; 287cabdff1aSopenharmony_ci } 288cabdff1aSopenharmony_ci } else { 289cabdff1aSopenharmony_ci switch (depth) { 290cabdff1aSopenharmony_ci case 1: 291cabdff1aSopenharmony_ci for (i = 0; i < avctx->height; i++) { 292cabdff1aSopenharmony_ci int j; 293cabdff1aSopenharmony_ci for (j = 0; j < avctx->width >> 3; j++) { 294cabdff1aSopenharmony_ci ptr[j*8+0] = buf[j] >> 7; 295cabdff1aSopenharmony_ci ptr[j*8+1] = (buf[j] >> 6) & 1; 296cabdff1aSopenharmony_ci ptr[j*8+2] = (buf[j] >> 5) & 1; 297cabdff1aSopenharmony_ci ptr[j*8+3] = (buf[j] >> 4) & 1; 298cabdff1aSopenharmony_ci ptr[j*8+4] = (buf[j] >> 3) & 1; 299cabdff1aSopenharmony_ci ptr[j*8+5] = (buf[j] >> 2) & 1; 300cabdff1aSopenharmony_ci ptr[j*8+6] = (buf[j] >> 1) & 1; 301cabdff1aSopenharmony_ci ptr[j*8+7] = buf[j] & 1; 302cabdff1aSopenharmony_ci } 303cabdff1aSopenharmony_ci for (j = 0; j < (avctx->width & 7); j++) { 304cabdff1aSopenharmony_ci ptr[avctx->width - (avctx->width & 7) + j] = buf[avctx->width >> 3] >> (7 - j) & 1; 305cabdff1aSopenharmony_ci } 306cabdff1aSopenharmony_ci buf += n; 307cabdff1aSopenharmony_ci ptr += linesize; 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci break; 310cabdff1aSopenharmony_ci case 8: 311cabdff1aSopenharmony_ci case 24: 312cabdff1aSopenharmony_ci case 32: 313cabdff1aSopenharmony_ci for (i = 0; i < avctx->height; i++) { 314cabdff1aSopenharmony_ci memcpy(ptr, buf, n); 315cabdff1aSopenharmony_ci buf += n; 316cabdff1aSopenharmony_ci ptr += linesize; 317cabdff1aSopenharmony_ci } 318cabdff1aSopenharmony_ci break; 319cabdff1aSopenharmony_ci case 4: 320cabdff1aSopenharmony_ci for (i = 0; i < avctx->height; i++) { 321cabdff1aSopenharmony_ci int j; 322cabdff1aSopenharmony_ci for (j = 0; j < n; j++) { 323cabdff1aSopenharmony_ci ptr[j*2+0] = (buf[j] >> 4) & 0xF; 324cabdff1aSopenharmony_ci ptr[j*2+1] = buf[j] & 0xF; 325cabdff1aSopenharmony_ci } 326cabdff1aSopenharmony_ci buf += n; 327cabdff1aSopenharmony_ci ptr += linesize; 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci break; 330cabdff1aSopenharmony_ci case 16: 331cabdff1aSopenharmony_ci for (i = 0; i < avctx->height; i++) { 332cabdff1aSopenharmony_ci const uint16_t *src = (const uint16_t *) buf; 333cabdff1aSopenharmony_ci uint16_t *dst = (uint16_t *) ptr; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci for (j = 0; j < avctx->width; j++) 336cabdff1aSopenharmony_ci *dst++ = av_le2ne16(*src++); 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci buf += n; 339cabdff1aSopenharmony_ci ptr += linesize; 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci break; 342cabdff1aSopenharmony_ci default: 343cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); 344cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci } 347cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_BGRA) { 348cabdff1aSopenharmony_ci for (i = 0; i < avctx->height; i++) { 349cabdff1aSopenharmony_ci int j; 350cabdff1aSopenharmony_ci uint8_t *ptr = p->data[0] + p->linesize[0]*i + 3; 351cabdff1aSopenharmony_ci for (j = 0; j < avctx->width; j++) { 352cabdff1aSopenharmony_ci if (ptr[4*j]) 353cabdff1aSopenharmony_ci break; 354cabdff1aSopenharmony_ci } 355cabdff1aSopenharmony_ci if (j < avctx->width) 356cabdff1aSopenharmony_ci break; 357cabdff1aSopenharmony_ci } 358cabdff1aSopenharmony_ci if (i == avctx->height) 359cabdff1aSopenharmony_ci avctx->pix_fmt = p->format = AV_PIX_FMT_BGR0; 360cabdff1aSopenharmony_ci } 361cabdff1aSopenharmony_ci 362cabdff1aSopenharmony_ci *got_frame = 1; 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci return buf_size; 365cabdff1aSopenharmony_ci} 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_ciconst FFCodec ff_bmp_decoder = { 368cabdff1aSopenharmony_ci .p.name = "bmp", 369cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), 370cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 371cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_BMP, 372cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 373cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(bmp_decode_frame), 374cabdff1aSopenharmony_ci}; 375