Mercurial > libavcodec.hg
annotate pnm.c @ 9002:eb98d61af310 libavcodec
Support 48-bit RGB PPM image.
| author | pross |
|---|---|
| date | Sun, 22 Feb 2009 00:56:55 +0000 |
| parents | 04423b2f6e0b |
| children | de31b10455cc |
| rev | line source |
|---|---|
| 4978 | 1 /* |
| 2 * PNM image format | |
|
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
7865
diff
changeset
|
3 * Copyright (c) 2002, 2003 Fabrice Bellard |
| 4978 | 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 #include "avcodec.h" | |
| 22 #include "pnm.h" | |
| 23 | |
| 24 static inline int pnm_space(int c) | |
| 25 { | |
| 6750 | 26 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; |
| 4978 | 27 } |
| 28 | |
| 29 static void pnm_get(PNMContext *sc, char *str, int buf_size) | |
| 30 { | |
| 31 char *s; | |
| 32 int c; | |
| 33 | |
| 34 /* skip spaces and comments */ | |
| 35 for(;;) { | |
| 36 c = *sc->bytestream++; | |
| 37 if (c == '#') { | |
| 38 do { | |
| 39 c = *sc->bytestream++; | |
| 40 } while (c != '\n' && sc->bytestream < sc->bytestream_end); | |
| 41 } else if (!pnm_space(c)) { | |
| 42 break; | |
| 43 } | |
| 44 } | |
| 45 | |
| 46 s = str; | |
| 47 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { | |
| 48 if ((s - str) < buf_size - 1) | |
| 49 *s++ = c; | |
| 50 c = *sc->bytestream++; | |
| 51 } | |
| 52 *s = '\0'; | |
| 53 } | |
| 54 | |
| 55 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ | |
| 56 char buf1[32], tuple_type[32]; | |
| 57 int h, w, depth, maxval; | |
| 58 | |
| 59 pnm_get(s, buf1, sizeof(buf1)); | |
| 60 if (!strcmp(buf1, "P4")) { | |
| 61 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
| 62 } else if (!strcmp(buf1, "P5")) { | |
| 63 if (avctx->codec_id == CODEC_ID_PGMYUV) | |
| 64 avctx->pix_fmt = PIX_FMT_YUV420P; | |
| 65 else | |
| 66 avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 67 } else if (!strcmp(buf1, "P6")) { | |
| 68 avctx->pix_fmt = PIX_FMT_RGB24; | |
| 69 } else if (!strcmp(buf1, "P7")) { | |
| 70 w = -1; | |
| 71 h = -1; | |
| 72 maxval = -1; | |
| 73 depth = -1; | |
| 74 tuple_type[0] = '\0'; | |
| 75 for(;;) { | |
| 76 pnm_get(s, buf1, sizeof(buf1)); | |
| 77 if (!strcmp(buf1, "WIDTH")) { | |
| 78 pnm_get(s, buf1, sizeof(buf1)); | |
| 79 w = strtol(buf1, NULL, 10); | |
| 80 } else if (!strcmp(buf1, "HEIGHT")) { | |
| 81 pnm_get(s, buf1, sizeof(buf1)); | |
| 82 h = strtol(buf1, NULL, 10); | |
| 83 } else if (!strcmp(buf1, "DEPTH")) { | |
| 84 pnm_get(s, buf1, sizeof(buf1)); | |
| 85 depth = strtol(buf1, NULL, 10); | |
| 86 } else if (!strcmp(buf1, "MAXVAL")) { | |
| 87 pnm_get(s, buf1, sizeof(buf1)); | |
| 88 maxval = strtol(buf1, NULL, 10); | |
| 89 } else if (!strcmp(buf1, "TUPLETYPE")) { | |
| 90 pnm_get(s, tuple_type, sizeof(tuple_type)); | |
| 91 } else if (!strcmp(buf1, "ENDHDR")) { | |
| 92 break; | |
| 93 } else { | |
| 94 return -1; | |
| 95 } | |
| 96 } | |
| 97 /* check that all tags are present */ | |
| 98 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h)) | |
| 99 return -1; | |
| 100 | |
| 101 avctx->width = w; | |
| 102 avctx->height = h; | |
| 103 if (depth == 1) { | |
| 104 if (maxval == 1) | |
| 105 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
| 106 else | |
| 107 avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 108 } else if (depth == 3) { | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
109 if (maxval < 256) { |
| 4978 | 110 avctx->pix_fmt = PIX_FMT_RGB24; |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
111 } else { |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
112 av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n"); |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
113 avctx->pix_fmt = PIX_FMT_NONE; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
114 return -1; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
115 } |
| 4978 | 116 } else if (depth == 4) { |
| 117 avctx->pix_fmt = PIX_FMT_RGB32; | |
| 118 } else { | |
| 119 return -1; | |
| 120 } | |
| 121 return 0; | |
| 122 } else { | |
| 123 return -1; | |
| 124 } | |
| 125 pnm_get(s, buf1, sizeof(buf1)); | |
| 126 avctx->width = atoi(buf1); | |
| 127 if (avctx->width <= 0) | |
| 128 return -1; | |
| 129 pnm_get(s, buf1, sizeof(buf1)); | |
| 130 avctx->height = atoi(buf1); | |
| 131 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) | |
| 132 return -1; | |
| 133 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { | |
| 134 pnm_get(s, buf1, sizeof(buf1)); | |
| 135 s->maxval = atoi(buf1); | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
136 if (s->maxval >= 256) { |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
137 if (avctx->pix_fmt == PIX_FMT_GRAY8) { |
| 7865 | 138 avctx->pix_fmt = PIX_FMT_GRAY16BE; |
| 139 if (s->maxval != 65535) | |
| 140 avctx->pix_fmt = PIX_FMT_GRAY16; | |
| 9002 | 141 } if (avctx->pix_fmt == PIX_FMT_RGB24) { |
| 142 if (s->maxval > 255) | |
| 143 avctx->pix_fmt = PIX_FMT_RGB48BE; | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
144 } else { |
| 9002 | 145 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n"); |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
146 avctx->pix_fmt = PIX_FMT_NONE; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
147 return -1; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
148 } |
| 4978 | 149 } |
| 150 } | |
| 151 /* more check if YUV420 */ | |
| 152 if (avctx->pix_fmt == PIX_FMT_YUV420P) { | |
| 153 if ((avctx->width & 1) != 0) | |
| 154 return -1; | |
| 155 h = (avctx->height * 2); | |
| 156 if ((h % 3) != 0) | |
| 157 return -1; | |
| 158 h /= 3; | |
| 159 avctx->height = h; | |
| 160 } | |
| 161 return 0; | |
| 162 } |
