00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avcodec.h"
00022 #include "pnm.h"
00023
00024 static inline int pnm_space(int c)
00025 {
00026 return (c == ' ' || c == '\n' || c == '\r' || c == '\t');
00027 }
00028
00029 static void pnm_get(PNMContext *sc, char *str, int buf_size)
00030 {
00031 char *s;
00032 int c;
00033
00034
00035 for(;;) {
00036 c = *sc->bytestream++;
00037 if (c == '#') {
00038 do {
00039 c = *sc->bytestream++;
00040 } while (c != '\n' && sc->bytestream < sc->bytestream_end);
00041 } else if (!pnm_space(c)) {
00042 break;
00043 }
00044 }
00045
00046 s = str;
00047 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
00048 if ((s - str) < buf_size - 1)
00049 *s++ = c;
00050 c = *sc->bytestream++;
00051 }
00052 *s = '\0';
00053 }
00054
00055 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){
00056 char buf1[32], tuple_type[32];
00057 int h, w, depth, maxval;
00058
00059 pnm_get(s, buf1, sizeof(buf1));
00060 if (!strcmp(buf1, "P4")) {
00061 avctx->pix_fmt = PIX_FMT_MONOWHITE;
00062 } else if (!strcmp(buf1, "P5")) {
00063 if (avctx->codec_id == CODEC_ID_PGMYUV)
00064 avctx->pix_fmt = PIX_FMT_YUV420P;
00065 else
00066 avctx->pix_fmt = PIX_FMT_GRAY8;
00067 } else if (!strcmp(buf1, "P6")) {
00068 avctx->pix_fmt = PIX_FMT_RGB24;
00069 } else if (!strcmp(buf1, "P7")) {
00070 w = -1;
00071 h = -1;
00072 maxval = -1;
00073 depth = -1;
00074 tuple_type[0] = '\0';
00075 for(;;) {
00076 pnm_get(s, buf1, sizeof(buf1));
00077 if (!strcmp(buf1, "WIDTH")) {
00078 pnm_get(s, buf1, sizeof(buf1));
00079 w = strtol(buf1, NULL, 10);
00080 } else if (!strcmp(buf1, "HEIGHT")) {
00081 pnm_get(s, buf1, sizeof(buf1));
00082 h = strtol(buf1, NULL, 10);
00083 } else if (!strcmp(buf1, "DEPTH")) {
00084 pnm_get(s, buf1, sizeof(buf1));
00085 depth = strtol(buf1, NULL, 10);
00086 } else if (!strcmp(buf1, "MAXVAL")) {
00087 pnm_get(s, buf1, sizeof(buf1));
00088 maxval = strtol(buf1, NULL, 10);
00089 } else if (!strcmp(buf1, "TUPLETYPE")) {
00090 pnm_get(s, tuple_type, sizeof(tuple_type));
00091 } else if (!strcmp(buf1, "ENDHDR")) {
00092 break;
00093 } else {
00094 return -1;
00095 }
00096 }
00097
00098 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h))
00099 return -1;
00100
00101 avctx->width = w;
00102 avctx->height = h;
00103 if (depth == 1) {
00104 if (maxval == 1)
00105 avctx->pix_fmt = PIX_FMT_MONOWHITE;
00106 else
00107 avctx->pix_fmt = PIX_FMT_GRAY8;
00108 } else if (depth == 3) {
00109 avctx->pix_fmt = PIX_FMT_RGB24;
00110 } else if (depth == 4) {
00111 avctx->pix_fmt = PIX_FMT_RGB32;
00112 } else {
00113 return -1;
00114 }
00115 return 0;
00116 } else {
00117 return -1;
00118 }
00119 pnm_get(s, buf1, sizeof(buf1));
00120 avctx->width = atoi(buf1);
00121 if (avctx->width <= 0)
00122 return -1;
00123 pnm_get(s, buf1, sizeof(buf1));
00124 avctx->height = atoi(buf1);
00125 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
00126 return -1;
00127 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
00128 pnm_get(s, buf1, sizeof(buf1));
00129 s->maxval = atoi(buf1);
00130 if(s->maxval >= 256 && avctx->pix_fmt == PIX_FMT_GRAY8) {
00131 avctx->pix_fmt = PIX_FMT_GRAY16BE;
00132 if (s->maxval != 65535)
00133 avctx->pix_fmt = PIX_FMT_GRAY16;
00134 }
00135 }
00136
00137 if (avctx->pix_fmt == PIX_FMT_YUV420P) {
00138 if ((avctx->width & 1) != 0)
00139 return -1;
00140 h = (avctx->height * 2);
00141 if ((h % 3) != 0)
00142 return -1;
00143 h /= 3;
00144 avctx->height = h;
00145 }
00146 return 0;
00147 }