tiff.c 20.8 KB
Newer Older
Kostya Shishkov's avatar
Kostya Shishkov committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
20 21

/**
22
 * @file
23
 * TIFF image decoder
24 25
 * @author Konstantin Shishkov
 */
26

Kostya Shishkov's avatar
Kostya Shishkov committed
27
#include "avcodec.h"
28
#if CONFIG_ZLIB
Kostya Shishkov's avatar
Kostya Shishkov committed
29 30
#include <zlib.h>
#endif
31
#include "lzw.h"
32
#include "tiff.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
33
#include "faxcompr.h"
34
#include "libavutil/common.h"
35
#include "libavutil/intreadwrite.h"
36
#include "libavutil/imgutils.h"
37

Kostya Shishkov's avatar
Kostya Shishkov committed
38 39 40 41 42
typedef struct TiffContext {
    AVCodecContext *avctx;
    AVFrame picture;

    int width, height;
43
    unsigned int bpp, bppcount;
44 45
    uint32_t palette[256];
    int palette_is_set;
Kostya Shishkov's avatar
Kostya Shishkov committed
46
    int le;
47
    enum TiffCompr compr;
48
    int invert;
Michael Niedermayer's avatar
Michael Niedermayer committed
49
    int fax_opts;
50
    int predictor;
51
    int fill_order;
Kostya Shishkov's avatar
Kostya Shishkov committed
52

53
    int strips, rps, sstype;
Kostya Shishkov's avatar
Kostya Shishkov committed
54
    int sot;
Michael Niedermayer's avatar
Michael Niedermayer committed
55 56
    const uint8_t* stripdata;
    const uint8_t* stripsizes;
Kostya Shishkov's avatar
Kostya Shishkov committed
57
    int stripsize, stripoff;
58
    LZWState *lzw;
Kostya Shishkov's avatar
Kostya Shishkov committed
59 60
} TiffContext;

Michael Niedermayer's avatar
Michael Niedermayer committed
61
static int tget_short(const uint8_t **p, int le){
62
    int v = le ? AV_RL16(*p) : AV_RB16(*p);
Kostya Shishkov's avatar
Kostya Shishkov committed
63 64 65 66
    *p += 2;
    return v;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
67
static int tget_long(const uint8_t **p, int le){
68
    int v = le ? AV_RL32(*p) : AV_RB32(*p);
Kostya Shishkov's avatar
Kostya Shishkov committed
69 70 71 72
    *p += 4;
    return v;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
73
static int tget(const uint8_t **p, int type, int le){
Kostya Shishkov's avatar
Kostya Shishkov committed
74 75 76 77 78 79 80 81
    switch(type){
    case TIFF_BYTE : return *(*p)++;
    case TIFF_SHORT: return tget_short(p, le);
    case TIFF_LONG : return tget_long (p, le);
    default        : return -1;
    }
}

82
#if CONFIG_ZLIB
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, int size)
{
    z_stream zstream;
    int zret;

    memset(&zstream, 0, sizeof(zstream));
    zstream.next_in = src;
    zstream.avail_in = size;
    zstream.next_out = dst;
    zstream.avail_out = *len;
    zret = inflateInit(&zstream);
    if (zret != Z_OK) {
        av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
        return zret;
    }
    zret = inflate(&zstream, Z_SYNC_FLUSH);
    inflateEnd(&zstream);
    *len = zstream.total_out;
    return zret == Z_STREAM_END ? Z_OK : zret;
}
103
#endif
104

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
                                             int usePtr, const uint8_t *src,
                                             uint8_t c, int width, int offset)
{
    int i;

    if (bpp == 2) {
        for (i = 0; i < width; i++) {
            dst[(i+offset)*4+0] = (usePtr ? src[i] : c) >> 6;
            dst[(i+offset)*4+1] = (usePtr ? src[i] : c) >> 4 & 0x3;
            dst[(i+offset)*4+2] = (usePtr ? src[i] : c) >> 2 & 0x3;
            dst[(i+offset)*4+3] = (usePtr ? src[i] : c) & 0x3;
        }
    } else if (bpp == 4) {
        for (i = 0; i < width; i++) {
            dst[(i+offset)*2+0] = (usePtr ? src[i] : c) >> 4;
            dst[(i+offset)*2+1] = (usePtr ? src[i] : c) & 0xF;
        }
    } else {
        if (usePtr) {
            memcpy(dst + offset, src, width);
        } else {
            memset(dst + offset, c, width);
        }
    }
}

132 133 134 135 136 137 138 139 140 141
static void av_always_inline split_nibbles(uint8_t *dst, const uint8_t *src,
                                           int width)
{
    while (--width >= 0) {
        // src == dst for LZW
        dst[width * 2 + 1] = src[width] & 0xF;
        dst[width * 2 + 0] = src[width] >> 4;
    }
}

Michael Niedermayer's avatar
Michael Niedermayer committed
142
static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){
Kostya Shishkov's avatar
Kostya Shishkov committed
143
    int c, line, pixels, code;
Michael Niedermayer's avatar
Michael Niedermayer committed
144
    const uint8_t *ssrc = src;
145
    int width = ((s->width * s->bpp) + 7) >> 3;
146
#if CONFIG_ZLIB
Kostya Shishkov's avatar
Kostya Shishkov committed
147 148 149
    uint8_t *zbuf; unsigned long outlen;

    if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
150
        int ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
151 152
        outlen = width * lines;
        zbuf = av_malloc(outlen);
153 154 155
        ret = tiff_uncompress(zbuf, &outlen, src, size);
        if(ret != Z_OK){
            av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret);
Kostya Shishkov's avatar
Kostya Shishkov committed
156 157 158 159 160
            av_free(zbuf);
            return -1;
        }
        src = zbuf;
        for(line = 0; line < lines; line++){
161 162 163 164 165
            if(s->bpp == 4){
                split_nibbles(dst, src, width);
            }else{
                memcpy(dst, src, width);
            }
Kostya Shishkov's avatar
Kostya Shishkov committed
166 167 168 169 170 171 172
            dst += stride;
            src += width;
        }
        av_free(zbuf);
        return 0;
    }
#endif
173 174 175 176 177 178
    if(s->compr == TIFF_LZW){
        if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){
            av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
            return -1;
        }
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
179 180 181 182 183 184 185 186
    if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){
        int i, ret = 0;
        uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);

        if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){
            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
            return -1;
        }
187 188 189 190 191
        if(s->fax_opts & 2){
            av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n");
            av_free(src2);
            return -1;
        }
192 193 194 195
        if(!s->fill_order){
            memcpy(src2, src, size);
        }else{
            for(i = 0; i < size; i++)
196
                src2[i] = av_reverse[src[i]];
197
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
198 199 200 201 202
        memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
        switch(s->compr){
        case TIFF_CCITT_RLE:
        case TIFF_G3:
        case TIFF_G4:
203
            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);
Michael Niedermayer's avatar
Michael Niedermayer committed
204 205 206 207 208
            break;
        }
        av_free(src2);
        return ret;
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
209 210 211 212 213 214 215
    for(line = 0; line < lines; line++){
        if(src - ssrc > size){
            av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
            return -1;
        }
        switch(s->compr){
        case TIFF_RAW:
216 217
            if (ssrc + size - src < width)
                return AVERROR_INVALIDDATA;
218
            if (!s->fill_order) {
219
                horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
220 221 222 223 224
            } else {
                int i;
                for (i = 0; i < width; i++)
                    dst[i] = av_reverse[src[i]];
            }
225
            src += width;
Kostya Shishkov's avatar
Kostya Shishkov committed
226 227 228 229 230 231 232 233 234 235
            break;
        case TIFF_PACKBITS:
            for(pixels = 0; pixels < width;){
                code = (int8_t)*src++;
                if(code >= 0){
                    code++;
                    if(pixels + code > width){
                        av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");
                        return -1;
                    }
236
                    horizontal_fill(s->bpp, dst, 1, src, 0, code, pixels);
Kostya Shishkov's avatar
Kostya Shishkov committed
237 238 239 240 241 242 243 244 245
                    src += code;
                    pixels += code;
                }else if(code != -128){ // -127..-1
                    code = (-code) + 1;
                    if(pixels + code > width){
                        av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
                        return -1;
                    }
                    c = *src++;
246
                    horizontal_fill(s->bpp, dst, 0, NULL, c, code, pixels);
Kostya Shishkov's avatar
Kostya Shishkov committed
247 248 249 250
                    pixels += code;
                }
            }
            break;
251 252 253 254 255 256
        case TIFF_LZW:
            pixels = ff_lzw_decode(s->lzw, dst, width);
            if(pixels < width){
                av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width);
                return -1;
            }
257 258
            if(s->bpp == 4)
                split_nibbles(dst, dst, width);
259
            break;
Kostya Shishkov's avatar
Kostya Shishkov committed
260 261 262 263 264 265
        }
        dst += stride;
    }
    return 0;
}

266 267 268 269 270 271 272 273 274
static int init_image(TiffContext *s)
{
    int i, ret;
    uint32_t *pal;

    switch (s->bpp * 10 + s->bppcount) {
    case 11:
        s->avctx->pix_fmt = PIX_FMT_MONOBLACK;
        break;
275 276
    case 21:
    case 41:
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
    case 81:
        s->avctx->pix_fmt = PIX_FMT_PAL8;
        break;
    case 243:
        s->avctx->pix_fmt = PIX_FMT_RGB24;
        break;
    case 161:
        s->avctx->pix_fmt = PIX_FMT_GRAY16BE;
        break;
    case 324:
        s->avctx->pix_fmt = PIX_FMT_RGBA;
        break;
    case 483:
        s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE;
        break;
    default:
        av_log(s->avctx, AV_LOG_ERROR,
               "This format is not supported (bpp=%d, bppcount=%d)\n",
               s->bpp, s->bppcount);
        return AVERROR_INVALIDDATA;
    }
    if (s->width != s->avctx->width || s->height != s->avctx->height) {
        if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
            return ret;
        avcodec_set_dimensions(s->avctx, s->width, s->height);
    }
    if (s->picture.data[0])
        s->avctx->release_buffer(s->avctx, &s->picture);
    if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }
309 310 311 312 313 314
    if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
        if (s->palette_is_set) {
            memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
        } else {
            /* make default grayscale pal */
            pal = (uint32_t *) s->picture.data[1];
315 316
            for (i = 0; i < 1<<s->bpp; i++)
                pal[i] = i * 255 / ((1<<s->bpp) - 1) * 0x010101;
317
        }
318 319 320
    }
    return 0;
}
Kostya Shishkov's avatar
Kostya Shishkov committed
321

322
static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf)
Kostya Shishkov's avatar
Kostya Shishkov committed
323 324
{
    int tag, type, count, off, value = 0;
325
    int i, j;
326
    uint32_t *pal;
Michael Niedermayer's avatar
Michael Niedermayer committed
327
    const uint8_t *rp, *gp, *bp;
Kostya Shishkov's avatar
Kostya Shishkov committed
328

329 330
    if (end_buf - buf < 12)
        return -1;
Kostya Shishkov's avatar
Kostya Shishkov committed
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    tag = tget_short(&buf, s->le);
    type = tget_short(&buf, s->le);
    count = tget_long(&buf, s->le);
    off = tget_long(&buf, s->le);

    if(count == 1){
        switch(type){
        case TIFF_BYTE:
        case TIFF_SHORT:
            buf -= 4;
            value = tget(&buf, type, s->le);
            buf = NULL;
            break;
        case TIFF_LONG:
            value = off;
            buf = NULL;
            break;
348 349 350 351 352
        case TIFF_STRING:
            if(count <= 4){
                buf -= 4;
                break;
            }
Kostya Shishkov's avatar
Kostya Shishkov committed
353 354 355 356
        default:
            value = -1;
            buf = start + off;
        }
357 358
    }else if(type_sizes[type] * count <= 4){
        buf -= 4;
Kostya Shishkov's avatar
Kostya Shishkov committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    }else{
        buf = start + off;
    }

    if(buf && (buf < start || buf > end_buf)){
        av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
        return -1;
    }

    switch(tag){
    case TIFF_WIDTH:
        s->width = value;
        break;
    case TIFF_HEIGHT:
        s->height = value;
        break;
    case TIFF_BPP:
376
        s->bppcount = count;
377 378 379 380
        if(count > 4){
            av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count);
            return -1;
        }
Kostya Shishkov's avatar
Kostya Shishkov committed
381 382 383 384
        if(count == 1) s->bpp = value;
        else{
            switch(type){
            case TIFF_BYTE:
385
                s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
Kostya Shishkov's avatar
Kostya Shishkov committed
386 387 388
                break;
            case TIFF_SHORT:
            case TIFF_LONG:
389
                s->bpp = 0;
390
                for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le);
Kostya Shishkov's avatar
Kostya Shishkov committed
391 392 393 394 395
                break;
            default:
                s->bpp = -1;
            }
        }
396 397 398 399 400 401
        break;
    case TIFF_SAMPLES_PER_PIXEL:
        if (count != 1) {
            av_log(s->avctx, AV_LOG_ERROR,
                   "Samples per pixel requires a single value, many provided\n");
            return AVERROR_INVALIDDATA;
402
        }
403 404 405
        if (s->bppcount == 1)
            s->bpp *= value;
        s->bppcount = value;
Kostya Shishkov's avatar
Kostya Shishkov committed
406 407 408
        break;
    case TIFF_COMPR:
        s->compr = value;
409
        s->predictor = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
410 411 412
        switch(s->compr){
        case TIFF_RAW:
        case TIFF_PACKBITS:
413
        case TIFF_LZW:
Michael Niedermayer's avatar
Michael Niedermayer committed
414 415 416 417 418
        case TIFF_CCITT_RLE:
            break;
        case TIFF_G3:
        case TIFF_G4:
            s->fax_opts = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
419 420 421
            break;
        case TIFF_DEFLATE:
        case TIFF_ADOBE_DEFLATE:
422
#if CONFIG_ZLIB
Kostya Shishkov's avatar
Kostya Shishkov committed
423 424 425 426 427
            break;
#else
            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
            return -1;
#endif
428 429 430 431
        case TIFF_JPEG:
        case TIFF_NEWJPEG:
            av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n");
            return -1;
Kostya Shishkov's avatar
Kostya Shishkov committed
432 433 434 435 436 437
        default:
            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
            return -1;
        }
        break;
    case TIFF_ROWSPERSTRIP:
438 439
        if(type == TIFF_LONG && value == -1)
            value = s->avctx->height;
440
        if(value < 1){
Kostya Shishkov's avatar
Kostya Shishkov committed
441 442 443 444 445 446 447 448 449 450 451 452
            av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
            return -1;
        }
        s->rps = value;
        break;
    case TIFF_STRIP_OFFS:
        if(count == 1){
            s->stripdata = NULL;
            s->stripoff = value;
        }else
            s->stripdata = start + off;
        s->strips = count;
453
        if(s->strips == 1) s->rps = s->height;
Kostya Shishkov's avatar
Kostya Shishkov committed
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
        s->sot = type;
        if(s->stripdata > end_buf){
            av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
            return -1;
        }
        break;
    case TIFF_STRIP_SIZE:
        if(count == 1){
            s->stripsizes = NULL;
            s->stripsize = value;
            s->strips = 1;
        }else{
            s->stripsizes = start + off;
        }
        s->strips = count;
469
        s->sstype = type;
Kostya Shishkov's avatar
Kostya Shishkov committed
470 471 472 473 474 475
        if(s->stripsizes > end_buf){
            av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
            return -1;
        }
        break;
    case TIFF_PREDICTOR:
476
        s->predictor = value;
Kostya Shishkov's avatar
Kostya Shishkov committed
477
        break;
478 479 480 481 482 483 484 485
    case TIFF_INVERT:
        switch(value){
        case 0:
            s->invert = 1;
            break;
        case 1:
            s->invert = 0;
            break;
486 487 488 489 490 491
        case 2:
        case 3:
            break;
        default:
            av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);
            return -1;
492 493
        }
        break;
494 495 496 497 498 499 500
    case TIFF_FILL_ORDER:
        if(value < 1 || value > 2){
            av_log(s->avctx, AV_LOG_ERROR, "Unknown FillOrder value %d, trying default one\n", value);
            value = 1;
        }
        s->fill_order = value - 1;
        break;
501
    case TIFF_PAL:
502
        pal = (uint32_t *) s->palette;
503
        off = type_sizes[type];
504 505
        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
            return -1;
506 507 508
        rp = buf;
        gp = buf + count / 3 * off;
        bp = buf + count / 3 * off * 2;
509
        off = (type_sizes[type] - 1) << 3;
510
        for(i = 0; i < count / 3; i++){
511 512
            j = 0xff << 24;
            j |= (tget(&rp, type, s->le) >> off) << 16;
513 514 515 516
            j |= (tget(&gp, type, s->le) >> off) << 8;
            j |= tget(&bp, type, s->le) >> off;
            pal[i] = j;
        }
517
        s->palette_is_set = 1;
518 519 520 521 522 523 524
        break;
    case TIFF_PLANAR:
        if(value == 2){
            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
            return -1;
        }
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
525
    case TIFF_T4OPTIONS:
526 527 528
        if(s->compr == TIFF_G3)
            s->fax_opts = value;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
529
    case TIFF_T6OPTIONS:
530 531
        if(s->compr == TIFF_G4)
            s->fax_opts = value;
Michael Niedermayer's avatar
Michael Niedermayer committed
532
        break;
533 534
    default:
        av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", tag, tag);
Kostya Shishkov's avatar
Kostya Shishkov committed
535 536 537 538 539 540
    }
    return 0;
}

static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
541
                        AVPacket *avpkt)
Kostya Shishkov's avatar
Kostya Shishkov committed
542
{
543 544
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Kostya Shishkov's avatar
Kostya Shishkov committed
545 546 547
    TiffContext * const s = avctx->priv_data;
    AVFrame *picture = data;
    AVFrame * const p= (AVFrame*)&s->picture;
Michael Niedermayer's avatar
Michael Niedermayer committed
548
    const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
549 550
    unsigned off;
    int id, le, ret;
551
    int i, j, entries;
552 553
    int stride;
    unsigned soff, ssize;
554
    uint8_t *dst;
Kostya Shishkov's avatar
Kostya Shishkov committed
555 556

    //parse image header
557 558
    if (end_buf - buf < 8)
        return AVERROR_INVALIDDATA;
559
    id = AV_RL16(buf); buf += 2;
Kostya Shishkov's avatar
Kostya Shishkov committed
560 561 562 563 564 565 566
    if(id == 0x4949) le = 1;
    else if(id == 0x4D4D) le = 0;
    else{
        av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
        return -1;
    }
    s->le = le;
567
    s->invert = 0;
568
    s->compr = TIFF_RAW;
569
    s->fill_order = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
570 571 572 573 574 575 576 577
    // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
    // that further identifies the file as a TIFF file"
    if(tget_short(&buf, le) != 42){
        av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
        return -1;
    }
    /* parse image file directory */
    off = tget_long(&buf, le);
578
    if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
Kostya Shishkov's avatar
Kostya Shishkov committed
579
        av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
580
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
581 582 583 584
    }
    buf = orig_buf + off;
    entries = tget_short(&buf, le);
    for(i = 0; i < entries; i++){
585
        if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0)
Kostya Shishkov's avatar
Kostya Shishkov committed
586 587 588
            return -1;
        buf += 12;
    }
589 590 591 592 593
    if(!s->stripdata && !s->stripoff){
        av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
        return -1;
    }
    /* now we have the data and may start decoding */
594 595 596
    if ((ret = init_image(s)) < 0)
        return ret;

597 598 599 600 601 602 603
    if(s->strips == 1 && !s->stripsize){
        av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
        s->stripsize = buf_size - s->stripoff;
    }
    stride = p->linesize[0];
    dst = p->data[0];
    for(i = 0; i < s->height; i += s->rps){
604 605 606
        if(s->stripsizes) {
            if (s->stripsizes >= end_buf)
                return AVERROR_INVALIDDATA;
607
            ssize = tget(&s->stripsizes, s->sstype, s->le);
608
        } else
609 610 611
            ssize = s->stripsize;

        if(s->stripdata){
612 613
            if (s->stripdata >= end_buf)
                return AVERROR_INVALIDDATA;
614 615 616
            soff = tget(&s->stripdata, s->sot, s->le);
        }else
            soff = s->stripoff;
617 618 619 620

        if (soff > buf_size || ssize > buf_size - soff) {
            av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
            return -1;
621
        }
622 623 624 625 626 627 628 629
        if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0)
            break;
        dst += s->rps * stride;
    }
    if(s->predictor == 2){
        dst = p->data[0];
        soff = s->bpp >> 3;
        ssize = s->width * soff;
630 631 632 633 634 635 636 637 638 639 640 641 642
        if (s->avctx->pix_fmt == PIX_FMT_RGB48LE) {
            for (i = 0; i < s->height; i++) {
                for (j = soff; j < ssize; j += 2)
                    AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
                dst += stride;
            }
        } else if (s->avctx->pix_fmt == PIX_FMT_RGB48BE) {
            for (i = 0; i < s->height; i++) {
                for (j = soff; j < ssize; j += 2)
                    AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
                dst += stride;
            }
        } else {
643 644 645 646 647
            for(i = 0; i < s->height; i++) {
                for(j = soff; j < ssize; j++)
                    dst[j] += dst[j - soff];
                dst += stride;
            }
648
        }
649
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
650

651
    if(s->invert){
652 653 654 655 656
        dst = s->picture.data[0];
        for(i = 0; i < s->height; i++){
            for(j = 0; j < s->picture.linesize[0]; j++)
                dst[j] = (s->avctx->pix_fmt == PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
            dst += s->picture.linesize[0];
657 658
        }
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
659 660 661 662 663 664
    *picture= *(AVFrame*)&s->picture;
    *data_size = sizeof(AVPicture);

    return buf_size;
}

665
static av_cold int tiff_init(AVCodecContext *avctx){
Kostya Shishkov's avatar
Kostya Shishkov committed
666 667 668 669 670 671 672
    TiffContext *s = avctx->priv_data;

    s->width = 0;
    s->height = 0;
    s->avctx = avctx;
    avcodec_get_frame_defaults((AVFrame*)&s->picture);
    avctx->coded_frame= (AVFrame*)&s->picture;
673
    ff_lzw_decode_open(&s->lzw);
Michael Niedermayer's avatar
Michael Niedermayer committed
674
    ff_ccitt_unpack_init();
Kostya Shishkov's avatar
Kostya Shishkov committed
675 676 677 678

    return 0;
}

679
static av_cold int tiff_end(AVCodecContext *avctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
680 681 682
{
    TiffContext * const s = avctx->priv_data;

683
    ff_lzw_decode_close(&s->lzw);
Kostya Shishkov's avatar
Kostya Shishkov committed
684 685 686 687 688
    if(s->picture.data[0])
        avctx->release_buffer(avctx, &s->picture);
    return 0;
}

689
AVCodec ff_tiff_decoder = {
690 691 692 693 694 695 696 697
    .name           = "tiff",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_TIFF,
    .priv_data_size = sizeof(TiffContext),
    .init           = tiff_init,
    .close          = tiff_end,
    .decode         = decode_frame,
    .capabilities   = CODEC_CAP_DR1,
698
    .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
Kostya Shishkov's avatar
Kostya Shishkov committed
699
};