1/* 2 * PNM image format 3 * Copyright (c) 2002, 2003 Fabrice Bellard 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "config_components.h" 23 24#include "avcodec.h" 25#include "codec_internal.h" 26#include "internal.h" 27#include "put_bits.h" 28#include "pnm.h" 29#include "half2float.h" 30 31static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval) 32{ 33 if (maxval <= 255) { 34 memcpy(dst, src, n); 35 } else { 36 int i; 37 for (i=0; i<n/2; i++) { 38 ((uint16_t *)dst)[i] = AV_RB16(src+2*i); 39 } 40 } 41} 42 43static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p, 44 int *got_frame, AVPacket *avpkt) 45{ 46 const uint8_t *buf = avpkt->data; 47 int buf_size = avpkt->size; 48 PNMContext * const s = avctx->priv_data; 49 int i, j, k, n, linesize, h, upgrade = 0, is_mono = 0; 50 unsigned char *ptr; 51 int components, sample_len, ret; 52 float scale; 53 54 s->bytestream_start = 55 s->bytestream = (uint8_t *)buf; 56 s->bytestream_end = (uint8_t *)buf + buf_size; 57 58 if ((ret = ff_pnm_decode_header(avctx, s)) < 0) 59 return ret; 60 61 if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 62 return ret; 63 p->pict_type = AV_PICTURE_TYPE_I; 64 p->key_frame = 1; 65 avctx->bits_per_raw_sample = av_log2(s->maxval) + 1; 66 67 switch (avctx->pix_fmt) { 68 default: 69 return AVERROR(EINVAL); 70 case AV_PIX_FMT_RGBA64: 71 n = avctx->width * 8; 72 components=4; 73 sample_len=16; 74 if (s->maxval < 65535) 75 upgrade = 2; 76 goto do_read; 77 case AV_PIX_FMT_RGB48: 78 n = avctx->width * 6; 79 components=3; 80 sample_len=16; 81 if (s->maxval < 65535) 82 upgrade = 2; 83 goto do_read; 84 case AV_PIX_FMT_RGBA: 85 n = avctx->width * 4; 86 components=4; 87 sample_len=8; 88 goto do_read; 89 case AV_PIX_FMT_RGB24: 90 n = avctx->width * 3; 91 components=3; 92 sample_len=8; 93 if (s->maxval < 255) 94 upgrade = 1; 95 goto do_read; 96 case AV_PIX_FMT_GRAY8: 97 n = avctx->width; 98 components=1; 99 sample_len=8; 100 if (s->maxval < 255) 101 upgrade = 1; 102 goto do_read; 103 case AV_PIX_FMT_GRAY8A: 104 n = avctx->width * 2; 105 components=2; 106 sample_len=8; 107 goto do_read; 108 case AV_PIX_FMT_GRAY16: 109 n = avctx->width * 2; 110 components=1; 111 sample_len=16; 112 if (s->maxval < 65535) 113 upgrade = 2; 114 goto do_read; 115 case AV_PIX_FMT_YA16: 116 n = avctx->width * 4; 117 components=2; 118 sample_len=16; 119 if (s->maxval < 65535) 120 upgrade = 2; 121 goto do_read; 122 case AV_PIX_FMT_MONOWHITE: 123 case AV_PIX_FMT_MONOBLACK: 124 n = (avctx->width + 7) >> 3; 125 components=1; 126 sample_len=1; 127 is_mono = 1; 128 do_read: 129 ptr = p->data[0]; 130 linesize = p->linesize[0]; 131 if (n * avctx->height > s->bytestream_end - s->bytestream) 132 return AVERROR_INVALIDDATA; 133 if(s->type < 4 || (is_mono && s->type==7)){ 134 for (i=0; i<avctx->height; i++) { 135 PutBitContext pb; 136 init_put_bits(&pb, ptr, linesize); 137 for(j=0; j<avctx->width * components; j++){ 138 unsigned int c=0; 139 unsigned v=0; 140 if(s->type < 4) 141 while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' )) 142 s->bytestream++; 143 if(s->bytestream >= s->bytestream_end) 144 return AVERROR_INVALIDDATA; 145 if (is_mono) { 146 /* read a single digit */ 147 v = (*s->bytestream++)&1; 148 } else { 149 /* read a sequence of digits */ 150 for (k = 0; k < 6 && c <= 9; k += 1) { 151 v = 10*v + c; 152 c = (*s->bytestream++) - '0'; 153 } 154 if (v > s->maxval) { 155 av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval); 156 return AVERROR_INVALIDDATA; 157 } 158 } 159 if (sample_len == 16) { 160 ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval; 161 } else 162 put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval); 163 } 164 if (sample_len != 16) 165 flush_put_bits(&pb); 166 ptr+= linesize; 167 } 168 }else{ 169 for (i = 0; i < avctx->height; i++) { 170 if (!upgrade) 171 samplecpy(ptr, s->bytestream, n, s->maxval); 172 else if (upgrade == 1) { 173 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; 174 for (j = 0; j < n; j++) 175 ptr[j] = (s->bytestream[j] * f + 64) >> 7; 176 } else if (upgrade == 2) { 177 unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval; 178 for (j = 0; j < n / 2; j++) { 179 v = AV_RB16(s->bytestream + 2*j); 180 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; 181 } 182 } 183 s->bytestream += n; 184 ptr += linesize; 185 } 186 } 187 break; 188 case AV_PIX_FMT_YUV420P: 189 case AV_PIX_FMT_YUV420P9: 190 case AV_PIX_FMT_YUV420P10: 191 { 192 unsigned char *ptr1, *ptr2; 193 194 n = avctx->width; 195 ptr = p->data[0]; 196 linesize = p->linesize[0]; 197 if (s->maxval >= 256) 198 n *= 2; 199 if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream) 200 return AVERROR_INVALIDDATA; 201 for (i = 0; i < avctx->height; i++) { 202 samplecpy(ptr, s->bytestream, n, s->maxval); 203 s->bytestream += n; 204 ptr += linesize; 205 } 206 ptr1 = p->data[1]; 207 ptr2 = p->data[2]; 208 n >>= 1; 209 h = avctx->height >> 1; 210 for (i = 0; i < h; i++) { 211 samplecpy(ptr1, s->bytestream, n, s->maxval); 212 s->bytestream += n; 213 samplecpy(ptr2, s->bytestream, n, s->maxval); 214 s->bytestream += n; 215 ptr1 += p->linesize[1]; 216 ptr2 += p->linesize[2]; 217 } 218 } 219 break; 220 case AV_PIX_FMT_YUV420P16: 221 { 222 uint16_t *ptr1, *ptr2; 223 const int f = (65535 * 32768 + s->maxval / 2) / s->maxval; 224 unsigned int j, v; 225 226 n = avctx->width * 2; 227 ptr = p->data[0]; 228 linesize = p->linesize[0]; 229 if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream) 230 return AVERROR_INVALIDDATA; 231 for (i = 0; i < avctx->height; i++) { 232 for (j = 0; j < n / 2; j++) { 233 v = AV_RB16(s->bytestream + 2*j); 234 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; 235 } 236 s->bytestream += n; 237 ptr += linesize; 238 } 239 ptr1 = (uint16_t*)p->data[1]; 240 ptr2 = (uint16_t*)p->data[2]; 241 n >>= 1; 242 h = avctx->height >> 1; 243 for (i = 0; i < h; i++) { 244 for (j = 0; j < n / 2; j++) { 245 v = AV_RB16(s->bytestream + 2*j); 246 ptr1[j] = (v * f + 16384) >> 15; 247 } 248 s->bytestream += n; 249 250 for (j = 0; j < n / 2; j++) { 251 v = AV_RB16(s->bytestream + 2*j); 252 ptr2[j] = (v * f + 16384) >> 15; 253 } 254 s->bytestream += n; 255 256 ptr1 += p->linesize[1] / 2; 257 ptr2 += p->linesize[2] / 2; 258 } 259 } 260 break; 261 case AV_PIX_FMT_GBRPF32: 262 if (!s->half) { 263 if (avctx->width * avctx->height * 12 > s->bytestream_end - s->bytestream) 264 return AVERROR_INVALIDDATA; 265 scale = 1.f / s->scale; 266 if (s->endian) { 267 float *r, *g, *b; 268 269 r = (float *)p->data[2]; 270 g = (float *)p->data[0]; 271 b = (float *)p->data[1]; 272 for (int i = 0; i < avctx->height; i++) { 273 for (int j = 0; j < avctx->width; j++) { 274 r[j] = av_int2float(AV_RL32(s->bytestream+0)) * scale; 275 g[j] = av_int2float(AV_RL32(s->bytestream+4)) * scale; 276 b[j] = av_int2float(AV_RL32(s->bytestream+8)) * scale; 277 s->bytestream += 12; 278 } 279 280 r += p->linesize[2] / 4; 281 g += p->linesize[0] / 4; 282 b += p->linesize[1] / 4; 283 } 284 } else { 285 float *r, *g, *b; 286 287 r = (float *)p->data[2]; 288 g = (float *)p->data[0]; 289 b = (float *)p->data[1]; 290 for (int i = 0; i < avctx->height; i++) { 291 for (int j = 0; j < avctx->width; j++) { 292 r[j] = av_int2float(AV_RB32(s->bytestream+0)) * scale; 293 g[j] = av_int2float(AV_RB32(s->bytestream+4)) * scale; 294 b[j] = av_int2float(AV_RB32(s->bytestream+8)) * scale; 295 s->bytestream += 12; 296 } 297 298 r += p->linesize[2] / 4; 299 g += p->linesize[0] / 4; 300 b += p->linesize[1] / 4; 301 } 302 } 303 } else { 304 if (avctx->width * avctx->height * 6 > s->bytestream_end - s->bytestream) 305 return AVERROR_INVALIDDATA; 306 scale = 1.f / s->scale; 307 if (s->endian) { 308 float *r, *g, *b; 309 310 r = (float *)p->data[2]; 311 g = (float *)p->data[0]; 312 b = (float *)p->data[1]; 313 for (int i = 0; i < avctx->height; i++) { 314 for (int j = 0; j < avctx->width; j++) { 315 r[j] = av_int2float(half2float(AV_RL16(s->bytestream+0), 316 s->mantissatable, 317 s->exponenttable, 318 s->offsettable)) * scale; 319 g[j] = av_int2float(half2float(AV_RL16(s->bytestream+2), 320 s->mantissatable, 321 s->exponenttable, 322 s->offsettable)) * scale; 323 b[j] = av_int2float(half2float(AV_RL16(s->bytestream+4), 324 s->mantissatable, 325 s->exponenttable, 326 s->offsettable)) * scale; 327 s->bytestream += 6; 328 } 329 330 r += p->linesize[2] / 4; 331 g += p->linesize[0] / 4; 332 b += p->linesize[1] / 4; 333 } 334 } else { 335 float *r, *g, *b; 336 337 r = (float *)p->data[2]; 338 g = (float *)p->data[0]; 339 b = (float *)p->data[1]; 340 for (int i = 0; i < avctx->height; i++) { 341 for (int j = 0; j < avctx->width; j++) { 342 r[j] = av_int2float(half2float(AV_RB16(s->bytestream+0), 343 s->mantissatable, 344 s->exponenttable, 345 s->offsettable)) * scale; 346 g[j] = av_int2float(half2float(AV_RB16(s->bytestream+2), 347 s->mantissatable, 348 s->exponenttable, 349 s->offsettable)) * scale; 350 b[j] = av_int2float(half2float(AV_RB16(s->bytestream+4), 351 s->mantissatable, 352 s->exponenttable, 353 s->offsettable)) * scale; 354 s->bytestream += 6; 355 } 356 357 r += p->linesize[2] / 4; 358 g += p->linesize[0] / 4; 359 b += p->linesize[1] / 4; 360 } 361 } } 362 break; 363 case AV_PIX_FMT_GRAYF32: 364 if (!s->half) { 365 if (avctx->width * avctx->height * 4 > s->bytestream_end - s->bytestream) 366 return AVERROR_INVALIDDATA; 367 scale = 1.f / s->scale; 368 if (s->endian) { 369 float *g = (float *)p->data[0]; 370 for (int i = 0; i < avctx->height; i++) { 371 for (int j = 0; j < avctx->width; j++) { 372 g[j] = av_int2float(AV_RL32(s->bytestream)) * scale; 373 s->bytestream += 4; 374 } 375 g += p->linesize[0] / 4; 376 } 377 } else { 378 float *g = (float *)p->data[0]; 379 for (int i = 0; i < avctx->height; i++) { 380 for (int j = 0; j < avctx->width; j++) { 381 g[j] = av_int2float(AV_RB32(s->bytestream)) * scale; 382 s->bytestream += 4; 383 } 384 g += p->linesize[0] / 4; 385 } 386 } 387 } else { 388 if (avctx->width * avctx->height * 2 > s->bytestream_end - s->bytestream) 389 return AVERROR_INVALIDDATA; 390 scale = 1.f / s->scale; 391 if (s->endian) { 392 float *g = (float *)p->data[0]; 393 for (int i = 0; i < avctx->height; i++) { 394 for (int j = 0; j < avctx->width; j++) { 395 g[j] = av_int2float(half2float(AV_RL16(s->bytestream), 396 s->mantissatable, 397 s->exponenttable, 398 s->offsettable)) * scale; 399 s->bytestream += 2; 400 } 401 g += p->linesize[0] / 4; 402 } 403 } else { 404 float *g = (float *)p->data[0]; 405 for (int i = 0; i < avctx->height; i++) { 406 for (int j = 0; j < avctx->width; j++) { 407 g[j] = av_int2float(half2float(AV_RB16(s->bytestream), 408 s->mantissatable, 409 s->exponenttable, 410 s->offsettable)) * scale; 411 s->bytestream += 2; 412 } 413 g += p->linesize[0] / 4; 414 } 415 } 416 } 417 break; 418 } 419 *got_frame = 1; 420 421 return s->bytestream - s->bytestream_start; 422} 423 424 425#if CONFIG_PGM_DECODER 426const FFCodec ff_pgm_decoder = { 427 .p.name = "pgm", 428 .p.long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), 429 .p.type = AVMEDIA_TYPE_VIDEO, 430 .p.id = AV_CODEC_ID_PGM, 431 .p.capabilities = AV_CODEC_CAP_DR1, 432 .priv_data_size = sizeof(PNMContext), 433 FF_CODEC_DECODE_CB(pnm_decode_frame), 434}; 435#endif 436 437#if CONFIG_PGMYUV_DECODER 438const FFCodec ff_pgmyuv_decoder = { 439 .p.name = "pgmyuv", 440 .p.long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), 441 .p.type = AVMEDIA_TYPE_VIDEO, 442 .p.id = AV_CODEC_ID_PGMYUV, 443 .p.capabilities = AV_CODEC_CAP_DR1, 444 .priv_data_size = sizeof(PNMContext), 445 FF_CODEC_DECODE_CB(pnm_decode_frame), 446}; 447#endif 448 449#if CONFIG_PPM_DECODER 450const FFCodec ff_ppm_decoder = { 451 .p.name = "ppm", 452 .p.long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), 453 .p.type = AVMEDIA_TYPE_VIDEO, 454 .p.id = AV_CODEC_ID_PPM, 455 .p.capabilities = AV_CODEC_CAP_DR1, 456 .priv_data_size = sizeof(PNMContext), 457 FF_CODEC_DECODE_CB(pnm_decode_frame), 458}; 459#endif 460 461#if CONFIG_PBM_DECODER 462const FFCodec ff_pbm_decoder = { 463 .p.name = "pbm", 464 .p.long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), 465 .p.type = AVMEDIA_TYPE_VIDEO, 466 .p.id = AV_CODEC_ID_PBM, 467 .p.capabilities = AV_CODEC_CAP_DR1, 468 .priv_data_size = sizeof(PNMContext), 469 FF_CODEC_DECODE_CB(pnm_decode_frame), 470}; 471#endif 472 473#if CONFIG_PAM_DECODER 474const FFCodec ff_pam_decoder = { 475 .p.name = "pam", 476 .p.long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), 477 .p.type = AVMEDIA_TYPE_VIDEO, 478 .p.id = AV_CODEC_ID_PAM, 479 .p.capabilities = AV_CODEC_CAP_DR1, 480 .priv_data_size = sizeof(PNMContext), 481 FF_CODEC_DECODE_CB(pnm_decode_frame), 482}; 483#endif 484 485#if CONFIG_PFM_DECODER 486const FFCodec ff_pfm_decoder = { 487 .p.name = "pfm", 488 .p.long_name = NULL_IF_CONFIG_SMALL("PFM (Portable FloatMap) image"), 489 .p.type = AVMEDIA_TYPE_VIDEO, 490 .p.id = AV_CODEC_ID_PFM, 491 .p.capabilities = AV_CODEC_CAP_DR1, 492 .priv_data_size = sizeof(PNMContext), 493 FF_CODEC_DECODE_CB(pnm_decode_frame), 494}; 495#endif 496 497#if CONFIG_PHM_DECODER 498static av_cold int phm_dec_init(AVCodecContext *avctx) 499{ 500 PNMContext *s = avctx->priv_data; 501 502 half2float_table(s->mantissatable, s->exponenttable, s->offsettable); 503 504 return 0; 505} 506 507const FFCodec ff_phm_decoder = { 508 .p.name = "phm", 509 .p.long_name = NULL_IF_CONFIG_SMALL("PHM (Portable HalfFloatMap) image"), 510 .p.type = AVMEDIA_TYPE_VIDEO, 511 .p.id = AV_CODEC_ID_PHM, 512 .p.capabilities = AV_CODEC_CAP_DR1, 513 .priv_data_size = sizeof(PNMContext), 514 .init = phm_dec_init, 515 FF_CODEC_DECODE_CB(pnm_decode_frame), 516}; 517#endif 518