diff options
author | Fabrice Bellard <fabrice@bellard.org> | 2003-04-19 15:18:00 +0000 |
---|---|---|
committer | Fabrice Bellard <fabrice@bellard.org> | 2003-04-19 15:18:00 +0000 |
commit | 8975ba81f8b949809e8d855168029011f14f2670 (patch) | |
tree | 45a4a9a530bdf0e87119c196632e72453de48829 | |
parent | 15e654b17bccd8cf1432b67d6522140b18ce22a9 (diff) | |
download | ffmpeg-8975ba81f8b949809e8d855168029011f14f2670.tar.gz |
added new netpbm pam format support (needed for alpha plane support)
Originally committed as revision 1792 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavformat/allformats.c | 1 | ||||
-rw-r--r-- | libavformat/avformat.h | 1 | ||||
-rw-r--r-- | libavformat/pnm.c | 197 |
3 files changed, 196 insertions, 3 deletions
diff --git a/libavformat/allformats.c b/libavformat/allformats.c index cd80136c64..5d602f3542 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -73,6 +73,7 @@ void av_register_all(void) av_register_image_format(&pbm_image_format); av_register_image_format(&pgm_image_format); av_register_image_format(&ppm_image_format); + av_register_image_format(&pam_image_format); av_register_image_format(&pgmyuv_image_format); av_register_image_format(&yuv_image_format); #ifdef CONFIG_ZLIB diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 872f231916..4a94a8ead3 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -253,6 +253,7 @@ extern AVImageFormat pnm_image_format; extern AVImageFormat pbm_image_format; extern AVImageFormat pgm_image_format; extern AVImageFormat ppm_image_format; +extern AVImageFormat pam_image_format; extern AVImageFormat pgmyuv_image_format; extern AVImageFormat yuv_image_format; #ifdef CONFIG_ZLIB diff --git a/libavformat/pnm.c b/libavformat/pnm.c index 38d7ab2280..2161faf069 100644 --- a/libavformat/pnm.c +++ b/libavformat/pnm.c @@ -202,7 +202,7 @@ static int pnm_write(ByteIOContext *pb, AVImageInfo *info) put_buffer(pb, ptr, n); ptr += linesize; } - + if (info->pix_fmt == PIX_FMT_YUV420P) { h >>= 1; n >>= 1; @@ -211,14 +211,183 @@ static int pnm_write(ByteIOContext *pb, AVImageInfo *info) for(i=0;i<h;i++) { put_buffer(pb, ptr1, n); put_buffer(pb, ptr2, n); - ptr1 += info->pict.linesize[1]; - ptr2 += info->pict.linesize[2]; + ptr1 += info->pict.linesize[1]; + ptr2 += info->pict.linesize[2]; } } put_flush_packet(pb); return 0; } + +static int pam_read(ByteIOContext *f, + int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) +{ + int i, n, linesize, h, w, depth, maxval; + char buf1[32], tuple_type[32]; + unsigned char *ptr; + AVImageInfo info1, *info = &info1; + int ret; + + pnm_get(f, buf1, sizeof(buf1)); + if (strcmp(buf1, "P7") != 0) + return AVERROR_INVALIDDATA; + w = -1; + h = -1; + maxval = -1; + depth = -1; + tuple_type[0] = '\0'; + for(;;) { + pnm_get(f, buf1, sizeof(buf1)); + if (!strcmp(buf1, "WIDTH")) { + pnm_get(f, buf1, sizeof(buf1)); + w = strtol(buf1, NULL, 10); + } else if (!strcmp(buf1, "HEIGHT")) { + pnm_get(f, buf1, sizeof(buf1)); + h = strtol(buf1, NULL, 10); + } else if (!strcmp(buf1, "DEPTH")) { + pnm_get(f, buf1, sizeof(buf1)); + depth = strtol(buf1, NULL, 10); + } else if (!strcmp(buf1, "MAXVAL")) { + pnm_get(f, buf1, sizeof(buf1)); + maxval = strtol(buf1, NULL, 10); + } else if (!strcmp(buf1, "TUPLETYPE")) { + pnm_get(f, buf1, sizeof(buf1)); + pstrcpy(tuple_type, sizeof(tuple_type), buf1); + } else if (!strcmp(buf1, "ENDHDR")) { + break; + } else { + return AVERROR_INVALIDDATA; + } + } + /* check that all tags are present */ + if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0') + return AVERROR_INVALIDDATA; + info->width = w; + info->height = h; + if (depth == 1) { + if (maxval == 1) + info->pix_fmt = PIX_FMT_MONOWHITE; + else + info->pix_fmt = PIX_FMT_GRAY8; + } else if (depth == 3) { + info->pix_fmt = PIX_FMT_RGB24; + } else if (depth == 4) { + info->pix_fmt = PIX_FMT_RGBA32; + } else { + return AVERROR_INVALIDDATA; + } + ret = alloc_cb(opaque, info); + if (ret) + return ret; + switch(info->pix_fmt) { + default: + return AVERROR_INVALIDDATA; + case PIX_FMT_RGB24: + n = info->width * 3; + goto do_read; + case PIX_FMT_GRAY8: + n = info->width; + goto do_read; + case PIX_FMT_MONOWHITE: + n = (info->width + 7) >> 3; + do_read: + ptr = info->pict.data[0]; + linesize = info->pict.linesize[0]; + for(i = 0; i < info->height; i++) { + get_buffer(f, ptr, n); + ptr += linesize; + } + break; + case PIX_FMT_RGBA32: + ptr = info->pict.data[0]; + linesize = info->pict.linesize[0]; + for(i = 0; i < info->height; i++) { + int j, r, g, b, a; + + for(j = 0;j < w; j++) { + r = get_byte(f); + g = get_byte(f); + b = get_byte(f); + a = get_byte(f); + ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; + } + ptr += linesize; + } + break; + } + return 0; +} + +static int pam_write(ByteIOContext *pb, AVImageInfo *info) +{ + int i, h, w, n, linesize, depth, maxval; + const char *tuple_type; + char buf[100]; + uint8_t *ptr; + + h = info->height; + w = info->width; + switch(info->pix_fmt) { + case PIX_FMT_MONOWHITE: + n = (info->width + 7) >> 3; + depth = 1; + maxval = 1; + tuple_type = "BLACKANDWHITE"; + break; + case PIX_FMT_GRAY8: + n = info->width; + depth = 1; + maxval = 255; + tuple_type = "GRAYSCALE"; + break; + case PIX_FMT_RGB24: + n = info->width * 3; + depth = 3; + maxval = 255; + tuple_type = "RGB"; + break; + case PIX_FMT_RGBA32: + n = info->width * 4; + depth = 4; + maxval = 255; + tuple_type = "RGB_ALPHA"; + break; + default: + return AVERROR_INVALIDDATA; + } + snprintf(buf, sizeof(buf), + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", + w, h, depth, maxval, tuple_type); + put_buffer(pb, buf, strlen(buf)); + + ptr = info->pict.data[0]; + linesize = info->pict.linesize[0]; + + if (info->pix_fmt == PIX_FMT_RGBA32) { + int j; + unsigned int v; + + for(i=0;i<h;i++) { + for(j=0;j<w;j++) { + v = ((uint32_t *)ptr)[j]; + put_byte(pb, (v >> 16) & 0xff); + put_byte(pb, (v >> 8) & 0xff); + put_byte(pb, (v) & 0xff); + put_byte(pb, (v >> 24) & 0xff); + } + ptr += linesize; + } + } else { + for(i=0;i<h;i++) { + put_buffer(pb, ptr, n); + ptr += linesize; + } + } + put_flush_packet(pb); + return 0; +} + static int pnm_probe(AVProbeData *pd) { const char *p = pd->buf; @@ -239,6 +408,18 @@ static int pgmyuv_probe(AVProbeData *pd) return 0; } +static int pam_probe(AVProbeData *pd) +{ + const char *p = pd->buf; + if (pd->buf_size >= 8 && + p[0] == 'P' && + p[1] == '7' && + p[2] == '\n') + return AVPROBE_SCORE_MAX; + else + return 0; +} + AVImageFormat pnm_image_format = { "pnm", NULL, @@ -275,6 +456,16 @@ AVImageFormat ppm_image_format = { pnm_write, }; +AVImageFormat pam_image_format = { + "pam", + "pam", + pam_probe, + pam_read, + (1 << PIX_FMT_MONOWHITE) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_RGB24) | + (1 << PIX_FMT_RGBA32), + pam_write, +}; + AVImageFormat pgmyuv_image_format = { "pgmyuv", NULL, |