00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #ifdef CONFIG_ZLIB
00029 #include <zlib.h>
00030 #endif
00031 #include "lzw.h"
00032 #include "tiff.h"
00033
00034
00035 typedef struct TiffContext {
00036 AVCodecContext *avctx;
00037 AVFrame picture;
00038
00039 int width, height;
00040 unsigned int bpp;
00041 int le;
00042 int compr;
00043 int invert;
00044
00045 int strips, rps;
00046 int sot;
00047 uint8_t* stripdata;
00048 uint8_t* stripsizes;
00049 int stripsize, stripoff;
00050 LZWState *lzw;
00051 } TiffContext;
00052
00053 static int tget_short(uint8_t **p, int le){
00054 int v = le ? AV_RL16(*p) : AV_RB16(*p);
00055 *p += 2;
00056 return v;
00057 }
00058
00059 static int tget_long(uint8_t **p, int le){
00060 int v = le ? AV_RL32(*p) : AV_RB32(*p);
00061 *p += 4;
00062 return v;
00063 }
00064
00065 static int tget(uint8_t **p, int type, int le){
00066 switch(type){
00067 case TIFF_BYTE : return *(*p)++;
00068 case TIFF_SHORT: return tget_short(p, le);
00069 case TIFF_LONG : return tget_long (p, le);
00070 default : return -1;
00071 }
00072 }
00073
00074 static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t *src, int size, int lines){
00075 int c, line, pixels, code;
00076 uint8_t *ssrc = src;
00077 int width = s->width * (s->bpp / 8);
00078 #ifdef CONFIG_ZLIB
00079 uint8_t *zbuf; unsigned long outlen;
00080
00081 if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
00082 outlen = width * lines;
00083 zbuf = av_malloc(outlen);
00084 if(uncompress(zbuf, &outlen, src, size) != Z_OK){
00085 av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu)\n", outlen, (unsigned long)width * lines);
00086 av_free(zbuf);
00087 return -1;
00088 }
00089 src = zbuf;
00090 for(line = 0; line < lines; line++){
00091 memcpy(dst, src, width);
00092 dst += stride;
00093 src += width;
00094 }
00095 av_free(zbuf);
00096 return 0;
00097 }
00098 #endif
00099 if(s->compr == TIFF_LZW){
00100 if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){
00101 av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
00102 return -1;
00103 }
00104 }
00105 for(line = 0; line < lines; line++){
00106 if(src - ssrc > size){
00107 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
00108 return -1;
00109 }
00110 switch(s->compr){
00111 case TIFF_RAW:
00112 memcpy(dst, src, s->width * (s->bpp / 8));
00113 src += s->width * (s->bpp / 8);
00114 break;
00115 case TIFF_PACKBITS:
00116 for(pixels = 0; pixels < width;){
00117 code = (int8_t)*src++;
00118 if(code >= 0){
00119 code++;
00120 if(pixels + code > width){
00121 av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");
00122 return -1;
00123 }
00124 memcpy(dst + pixels, src, code);
00125 src += code;
00126 pixels += code;
00127 }else if(code != -128){
00128 code = (-code) + 1;
00129 if(pixels + code > width){
00130 av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00131 return -1;
00132 }
00133 c = *src++;
00134 memset(dst + pixels, c, code);
00135 pixels += code;
00136 }
00137 }
00138 break;
00139 case TIFF_LZW:
00140 pixels = ff_lzw_decode(s->lzw, dst, width);
00141 if(pixels < width){
00142 av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width);
00143 return -1;
00144 }
00145 break;
00146 }
00147 dst += stride;
00148 }
00149 return 0;
00150 }
00151
00152
00153 static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic)
00154 {
00155 int tag, type, count, off, value = 0;
00156 uint8_t *src, *dst;
00157 int i, j, ssize, soff, stride;
00158 uint32_t *pal;
00159 uint8_t *rp, *gp, *bp;
00160
00161 tag = tget_short(&buf, s->le);
00162 type = tget_short(&buf, s->le);
00163 count = tget_long(&buf, s->le);
00164 off = tget_long(&buf, s->le);
00165
00166 if(count == 1){
00167 switch(type){
00168 case TIFF_BYTE:
00169 case TIFF_SHORT:
00170 buf -= 4;
00171 value = tget(&buf, type, s->le);
00172 buf = NULL;
00173 break;
00174 case TIFF_LONG:
00175 value = off;
00176 buf = NULL;
00177 break;
00178 default:
00179 value = -1;
00180 buf = start + off;
00181 }
00182 }else if(type_sizes[type] * count <= 4){
00183 buf -= 4;
00184 }else{
00185 buf = start + off;
00186 }
00187
00188 if(buf && (buf < start || buf > end_buf)){
00189 av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
00190 return -1;
00191 }
00192
00193 switch(tag){
00194 case TIFF_WIDTH:
00195 s->width = value;
00196 break;
00197 case TIFF_HEIGHT:
00198 s->height = value;
00199 break;
00200 case TIFF_BPP:
00201 if(count == 1) s->bpp = value;
00202 else{
00203 switch(type){
00204 case TIFF_BYTE:
00205 s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
00206 break;
00207 case TIFF_SHORT:
00208 case TIFF_LONG:
00209 s->bpp = 0;
00210 for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le);
00211 break;
00212 default:
00213 s->bpp = -1;
00214 }
00215 }
00216 switch(s->bpp){
00217 case 8:
00218 s->avctx->pix_fmt = PIX_FMT_PAL8;
00219 break;
00220 case 24:
00221 s->avctx->pix_fmt = PIX_FMT_RGB24;
00222 break;
00223 case 16:
00224 if(count == 1){
00225 s->avctx->pix_fmt = PIX_FMT_GRAY16BE;
00226 }else{
00227 av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%i)\n", s->bpp);
00228 return -1;
00229 }
00230 break;
00231 default:
00232 av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%i)\n", s->bpp);
00233 return -1;
00234 }
00235 if(s->width != s->avctx->width || s->height != s->avctx->height){
00236 if(avcodec_check_dimensions(s->avctx, s->width, s->height))
00237 return -1;
00238 avcodec_set_dimensions(s->avctx, s->width, s->height);
00239 }
00240 if(s->picture.data[0])
00241 s->avctx->release_buffer(s->avctx, &s->picture);
00242 if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){
00243 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00244 return -1;
00245 }
00246 if(s->bpp == 8){
00247
00248 pal = (uint32_t *) s->picture.data[1];
00249 for(i = 0; i < 256; i++)
00250 pal[i] = i * 0x010101;
00251 }
00252 break;
00253 case TIFF_COMPR:
00254 s->compr = value;
00255 switch(s->compr){
00256 case TIFF_RAW:
00257 case TIFF_PACKBITS:
00258 case TIFF_LZW:
00259 break;
00260 case TIFF_DEFLATE:
00261 case TIFF_ADOBE_DEFLATE:
00262 #ifdef CONFIG_ZLIB
00263 break;
00264 #else
00265 av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
00266 return -1;
00267 #endif
00268 case TIFF_G3:
00269 av_log(s->avctx, AV_LOG_ERROR, "CCITT G3 compression is not supported\n");
00270 return -1;
00271 case TIFF_G4:
00272 av_log(s->avctx, AV_LOG_ERROR, "CCITT G4 compression is not supported\n");
00273 return -1;
00274 case TIFF_CCITT_RLE:
00275 av_log(s->avctx, AV_LOG_ERROR, "CCITT RLE compression is not supported\n");
00276 return -1;
00277 case TIFF_JPEG:
00278 case TIFF_NEWJPEG:
00279 av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n");
00280 return -1;
00281 default:
00282 av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
00283 return -1;
00284 }
00285 break;
00286 case TIFF_ROWSPERSTRIP:
00287 if(value < 1){
00288 av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
00289 return -1;
00290 }
00291 s->rps = value;
00292 break;
00293 case TIFF_STRIP_OFFS:
00294 if(count == 1){
00295 s->stripdata = NULL;
00296 s->stripoff = value;
00297 }else
00298 s->stripdata = start + off;
00299 s->strips = count;
00300 if(s->strips == 1) s->rps = s->height;
00301 s->sot = type;
00302 if(s->stripdata > end_buf){
00303 av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
00304 return -1;
00305 }
00306 break;
00307 case TIFF_STRIP_SIZE:
00308 if(count == 1){
00309 s->stripsizes = NULL;
00310 s->stripsize = value;
00311 s->strips = 1;
00312 }else{
00313 s->stripsizes = start + off;
00314 }
00315 s->strips = count;
00316 if(s->stripsizes > end_buf){
00317 av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
00318 return -1;
00319 }
00320 if(!pic->data[0]){
00321 av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n");
00322 return -1;
00323 }
00324
00325 stride = pic->linesize[0];
00326 dst = pic->data[0];
00327 for(i = 0; i < s->height; i += s->rps){
00328 if(s->stripsizes)
00329 ssize = tget(&s->stripsizes, type, s->le);
00330 else
00331 ssize = s->stripsize;
00332
00333 if(s->stripdata){
00334 soff = tget(&s->stripdata, s->sot, s->le);
00335 }else
00336 soff = s->stripoff;
00337 src = start + soff;
00338 if(tiff_unpack_strip(s, dst, stride, src, ssize, FFMIN(s->rps, s->height - i)) < 0)
00339 break;
00340 dst += s->rps * stride;
00341 }
00342 break;
00343 case TIFF_PREDICTOR:
00344 if(!pic->data[0]){
00345 av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n");
00346 return -1;
00347 }
00348 if(value == 2){
00349 src = pic->data[0];
00350 stride = pic->linesize[0];
00351 soff = s->bpp >> 3;
00352 ssize = s->width * soff;
00353 for(i = 0; i < s->height; i++) {
00354 for(j = soff; j < ssize; j++)
00355 src[j] += src[j - soff];
00356 src += stride;
00357 }
00358 }
00359 break;
00360 case TIFF_INVERT:
00361 switch(value){
00362 case 0:
00363 s->invert = 1;
00364 break;
00365 case 1:
00366 s->invert = 0;
00367 break;
00368 case 2:
00369 case 3:
00370 break;
00371 default:
00372 av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);
00373 return -1;
00374 }
00375 break;
00376 case TIFF_PAL:
00377 if(s->avctx->pix_fmt != PIX_FMT_PAL8){
00378 av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n");
00379 return -1;
00380 }
00381 pal = (uint32_t *) s->picture.data[1];
00382 off = type_sizes[type];
00383 rp = buf;
00384 gp = buf + count / 3 * off;
00385 bp = buf + count / 3 * off * 2;
00386 off = (type_sizes[type] - 1) << 3;
00387 for(i = 0; i < count / 3; i++){
00388 j = (tget(&rp, type, s->le) >> off) << 16;
00389 j |= (tget(&gp, type, s->le) >> off) << 8;
00390 j |= tget(&bp, type, s->le) >> off;
00391 pal[i] = j;
00392 }
00393 break;
00394 case TIFF_PLANAR:
00395 if(value == 2){
00396 av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
00397 return -1;
00398 }
00399 break;
00400 }
00401 return 0;
00402 }
00403
00404 static int decode_frame(AVCodecContext *avctx,
00405 void *data, int *data_size,
00406 uint8_t *buf, int buf_size)
00407 {
00408 TiffContext * const s = avctx->priv_data;
00409 AVFrame *picture = data;
00410 AVFrame * const p= (AVFrame*)&s->picture;
00411 uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
00412 int id, le, off;
00413 int i, entries;
00414
00415
00416 id = AV_RL16(buf); buf += 2;
00417 if(id == 0x4949) le = 1;
00418 else if(id == 0x4D4D) le = 0;
00419 else{
00420 av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
00421 return -1;
00422 }
00423 s->le = le;
00424 s->invert = 0;
00425
00426
00427 if(tget_short(&buf, le) != 42){
00428 av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
00429 return -1;
00430 }
00431
00432 off = tget_long(&buf, le);
00433 if(orig_buf + off + 14 >= end_buf){
00434 av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
00435 return -1;
00436 }
00437 buf = orig_buf + off;
00438 entries = tget_short(&buf, le);
00439 for(i = 0; i < entries; i++){
00440 if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0)
00441 return -1;
00442 buf += 12;
00443 }
00444
00445 if(s->invert){
00446 uint8_t *src;
00447 int j;
00448
00449 src = s->picture.data[0];
00450 for(j = 0; j < s->height; j++){
00451 for(i = 0; i < s->picture.linesize[0]; i++)
00452 src[i] = 255 - src[i];
00453 src += s->picture.linesize[0];
00454 }
00455 }
00456 *picture= *(AVFrame*)&s->picture;
00457 *data_size = sizeof(AVPicture);
00458
00459 return buf_size;
00460 }
00461
00462 static int tiff_init(AVCodecContext *avctx){
00463 TiffContext *s = avctx->priv_data;
00464
00465 s->width = 0;
00466 s->height = 0;
00467 s->avctx = avctx;
00468 avcodec_get_frame_defaults((AVFrame*)&s->picture);
00469 avctx->coded_frame= (AVFrame*)&s->picture;
00470 s->picture.data[0] = NULL;
00471 ff_lzw_decode_open(&s->lzw);
00472
00473 return 0;
00474 }
00475
00476 static int tiff_end(AVCodecContext *avctx)
00477 {
00478 TiffContext * const s = avctx->priv_data;
00479
00480 ff_lzw_decode_close(&s->lzw);
00481 if(s->picture.data[0])
00482 avctx->release_buffer(avctx, &s->picture);
00483 return 0;
00484 }
00485
00486 AVCodec tiff_decoder = {
00487 "tiff",
00488 CODEC_TYPE_VIDEO,
00489 CODEC_ID_TIFF,
00490 sizeof(TiffContext),
00491 tiff_init,
00492 NULL,
00493 tiff_end,
00494 decode_frame,
00495 0,
00496 NULL
00497 };