tiff.c 19 KB
Newer Older
Kostya Shishkov's avatar
Kostya Shishkov committed
1 2 3 4
/*
 * TIFF image decoder
 * Copyright (c) 2006 Konstantin Shishkov
 *
5
 * This file is part of Libav.
Kostya Shishkov's avatar
Kostya Shishkov committed
6
 *
7
 * Libav is free software; you can redistribute it and/or
Kostya Shishkov's avatar
Kostya Shishkov committed
8 9 10 11
 * 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.
 *
12
 * Libav is distributed in the hope that it will be useful,
Kostya Shishkov's avatar
Kostya Shishkov committed
13 14 15 16 17
 * 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
18
 * License along with Libav; if not, write to the Free Software
Kostya Shishkov's avatar
Kostya Shishkov committed
19 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
21 22

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

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

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

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

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

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

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

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

83
#if CONFIG_ZLIB
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
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;
}
104
#endif
105

Michael Niedermayer's avatar
Michael Niedermayer committed
106
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
107
    int c, line, pixels, code;
Michael Niedermayer's avatar
Michael Niedermayer committed
108
    const uint8_t *ssrc = src;
109
    int width = ((s->width * s->bpp) + 7) >> 3;
110
#if CONFIG_ZLIB
Kostya Shishkov's avatar
Kostya Shishkov committed
111 112 113
    uint8_t *zbuf; unsigned long outlen;

    if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
114
        int ret;
Kostya Shishkov's avatar
Kostya Shishkov committed
115 116
        outlen = width * lines;
        zbuf = av_malloc(outlen);
117 118 119
        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
120 121 122 123 124 125 126 127 128 129 130 131 132
            av_free(zbuf);
            return -1;
        }
        src = zbuf;
        for(line = 0; line < lines; line++){
            memcpy(dst, src, width);
            dst += stride;
            src += width;
        }
        av_free(zbuf);
        return 0;
    }
#endif
133 134 135 136 137 138
    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
139 140 141 142 143 144 145 146
    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;
        }
147 148 149 150 151
        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;
        }
152 153 154 155
        if(!s->fill_order){
            memcpy(src2, src, size);
        }else{
            for(i = 0; i < size; i++)
156
                src2[i] = av_reverse[src[i]];
157
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
158 159 160 161 162
        memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
        switch(s->compr){
        case TIFF_CCITT_RLE:
        case TIFF_G3:
        case TIFF_G4:
163
            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);
Michael Niedermayer's avatar
Michael Niedermayer committed
164 165 166 167 168
            break;
        }
        av_free(src2);
        return ret;
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
169 170 171 172 173 174 175
    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:
176 177
            if (ssrc + size - src < width)
                return AVERROR_INVALIDDATA;
178 179 180 181 182 183 184
            if (!s->fill_order) {
                memcpy(dst, src, width);
            } else {
                int i;
                for (i = 0; i < width; i++)
                    dst[i] = av_reverse[src[i]];
            }
185
            src += width;
Kostya Shishkov's avatar
Kostya Shishkov committed
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
            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;
                    }
                    memcpy(dst + pixels, src, code);
                    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++;
                    memset(dst + pixels, c, code);
                    pixels += code;
                }
            }
            break;
211 212 213 214 215 216 217
        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;
            }
            break;
Kostya Shishkov's avatar
Kostya Shishkov committed
218 219 220 221 222 223
        }
        dst += stride;
    }
    return 0;
}

224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
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;
    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;
    }
265 266 267 268 269 270 271 272 273
    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];
            for (i = 0; i < 256; i++)
                pal[i] = i * 0x010101;
        }
274 275 276
    }
    return 0;
}
Kostya Shishkov's avatar
Kostya Shishkov committed
277

278
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
279
{
280
    unsigned tag, type, count, off, value = 0;
281
    int i, j;
282
    uint32_t *pal;
Michael Niedermayer's avatar
Michael Niedermayer committed
283
    const uint8_t *rp, *gp, *bp;
Kostya Shishkov's avatar
Kostya Shishkov committed
284

285 286
    if (end_buf - buf < 12)
        return -1;
Kostya Shishkov's avatar
Kostya Shishkov committed
287 288 289 290 291
    tag = tget_short(&buf, s->le);
    type = tget_short(&buf, s->le);
    count = tget_long(&buf, s->le);
    off = tget_long(&buf, s->le);

292 293 294 295 296
    if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
        av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type);
        return 0;
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
297 298 299 300 301 302 303 304 305 306 307 308
    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;
309 310 311 312 313
        case TIFF_STRING:
            if(count <= 4){
                buf -= 4;
                break;
            }
Kostya Shishkov's avatar
Kostya Shishkov committed
314
        default:
315
            value = UINT_MAX;
Kostya Shishkov's avatar
Kostya Shishkov committed
316 317
            buf = start + off;
        }
318 319 320 321 322 323
    } else {
        if (count <= 4 && type_sizes[type] * count <= 4) {
            buf -= 4;
        } else {
            buf = start + off;
        }
Kostya Shishkov's avatar
Kostya Shishkov committed
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    }

    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:
339
        s->bppcount = count;
340 341 342 343
        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
344 345 346 347
        if(count == 1) s->bpp = value;
        else{
            switch(type){
            case TIFF_BYTE:
348
                s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
Kostya Shishkov's avatar
Kostya Shishkov committed
349 350 351
                break;
            case TIFF_SHORT:
            case TIFF_LONG:
352
                s->bpp = 0;
353
                for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le);
Kostya Shishkov's avatar
Kostya Shishkov committed
354 355 356 357 358
                break;
            default:
                s->bpp = -1;
            }
        }
359 360 361 362 363 364
        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;
365
        }
366 367 368
        if (s->bppcount == 1)
            s->bpp *= value;
        s->bppcount = value;
Kostya Shishkov's avatar
Kostya Shishkov committed
369 370 371
        break;
    case TIFF_COMPR:
        s->compr = value;
372
        s->predictor = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
373 374 375
        switch(s->compr){
        case TIFF_RAW:
        case TIFF_PACKBITS:
376
        case TIFF_LZW:
Michael Niedermayer's avatar
Michael Niedermayer committed
377 378 379 380 381
        case TIFF_CCITT_RLE:
            break;
        case TIFF_G3:
        case TIFF_G4:
            s->fax_opts = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
382 383 384
            break;
        case TIFF_DEFLATE:
        case TIFF_ADOBE_DEFLATE:
385
#if CONFIG_ZLIB
Kostya Shishkov's avatar
Kostya Shishkov committed
386 387 388 389 390
            break;
#else
            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
            return -1;
#endif
391 392 393 394
        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
395 396 397 398 399 400
        default:
            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
            return -1;
        }
        break;
    case TIFF_ROWSPERSTRIP:
401
        if (type == TIFF_LONG && value == UINT_MAX)
402
            value = s->avctx->height;
403
        if(value < 1){
Kostya Shishkov's avatar
Kostya Shishkov committed
404 405 406 407 408 409 410 411 412 413 414 415
            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;
416
        if(s->strips == 1) s->rps = s->height;
Kostya Shishkov's avatar
Kostya Shishkov committed
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
        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;
432
        s->sstype = type;
Kostya Shishkov's avatar
Kostya Shishkov committed
433 434 435 436 437 438
        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:
439
        s->predictor = value;
Kostya Shishkov's avatar
Kostya Shishkov committed
440
        break;
441 442 443 444 445 446 447 448
    case TIFF_INVERT:
        switch(value){
        case 0:
            s->invert = 1;
            break;
        case 1:
            s->invert = 0;
            break;
449 450 451 452 453 454
        case 2:
        case 3:
            break;
        default:
            av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);
            return -1;
455 456
        }
        break;
457 458 459 460 461 462 463
    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;
464
    case TIFF_PAL:
465
        pal = (uint32_t *) s->palette;
466
        off = type_sizes[type];
467 468
        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
            return -1;
469 470 471
        rp = buf;
        gp = buf + count / 3 * off;
        bp = buf + count / 3 * off * 2;
472
        off = (type_sizes[type] - 1) << 3;
473 474 475 476 477 478
        for(i = 0; i < count / 3; i++){
            j = (tget(&rp, type, s->le) >> off) << 16;
            j |= (tget(&gp, type, s->le) >> off) << 8;
            j |= tget(&bp, type, s->le) >> off;
            pal[i] = j;
        }
479
        s->palette_is_set = 1;
480 481 482 483 484 485 486
        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
487
    case TIFF_T4OPTIONS:
488 489 490
        if(s->compr == TIFF_G3)
            s->fax_opts = value;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
491
    case TIFF_T6OPTIONS:
492 493
        if(s->compr == TIFF_G4)
            s->fax_opts = value;
Michael Niedermayer's avatar
Michael Niedermayer committed
494
        break;
495 496
    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
497 498 499 500 501 502
    }
    return 0;
}

static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
503
                        AVPacket *avpkt)
Kostya Shishkov's avatar
Kostya Shishkov committed
504
{
505 506
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Kostya Shishkov's avatar
Kostya Shishkov committed
507 508
    TiffContext * const s = avctx->priv_data;
    AVFrame *picture = data;
509
    AVFrame * const p = &s->picture;
Michael Niedermayer's avatar
Michael Niedermayer committed
510
    const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
511 512
    unsigned off;
    int id, le, ret;
513
    int i, j, entries;
514 515
    int stride;
    unsigned soff, ssize;
516
    uint8_t *dst;
Kostya Shishkov's avatar
Kostya Shishkov committed
517 518

    //parse image header
519 520
    if (end_buf - buf < 8)
        return AVERROR_INVALIDDATA;
521
    id = AV_RL16(buf); buf += 2;
Kostya Shishkov's avatar
Kostya Shishkov committed
522 523 524 525 526 527 528
    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;
529
    s->invert = 0;
530
    s->compr = TIFF_RAW;
531
    s->fill_order = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
532 533 534 535 536 537
    // 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;
    }
538 539
    // Reset these pointers so we can tell if they were set this frame
    s->stripsizes = s->stripdata = NULL;
Kostya Shishkov's avatar
Kostya Shishkov committed
540 541
    /* parse image file directory */
    off = tget_long(&buf, le);
542
    if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
Kostya Shishkov's avatar
Kostya Shishkov committed
543
        av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
544
        return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
545 546 547 548
    }
    buf = orig_buf + off;
    entries = tget_short(&buf, le);
    for(i = 0; i < entries; i++){
549
        if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0)
Kostya Shishkov's avatar
Kostya Shishkov committed
550 551 552
            return -1;
        buf += 12;
    }
553 554 555 556 557
    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 */
558 559 560
    if ((ret = init_image(s)) < 0)
        return ret;

561 562 563 564 565 566 567
    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){
568 569 570
        if(s->stripsizes) {
            if (s->stripsizes >= end_buf)
                return AVERROR_INVALIDDATA;
571
            ssize = tget(&s->stripsizes, s->sstype, s->le);
572
        } else
573 574 575
            ssize = s->stripsize;

        if(s->stripdata){
576 577
            if (s->stripdata >= end_buf)
                return AVERROR_INVALIDDATA;
578 579 580
            soff = tget(&s->stripdata, s->sot, s->le);
        }else
            soff = s->stripoff;
581 582 583 584

        if (soff > buf_size || ssize > buf_size - soff) {
            av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
            return -1;
585
        }
586 587 588 589 590 591 592 593 594 595 596 597 598 599
        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;
        for(i = 0; i < s->height; i++) {
            for(j = soff; j < ssize; j++)
                dst[j] += dst[j - soff];
            dst += stride;
        }
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
600

601 602 603 604 605 606 607 608 609 610 611
    if(s->invert){
        uint8_t *src;
        int j;

        src = s->picture.data[0];
        for(j = 0; j < s->height; j++){
            for(i = 0; i < s->picture.linesize[0]; i++)
                src[i] = 255 - src[i];
            src += s->picture.linesize[0];
        }
    }
612
    *picture   = s->picture;
Kostya Shishkov's avatar
Kostya Shishkov committed
613 614 615 616 617
    *data_size = sizeof(AVPicture);

    return buf_size;
}

618
static av_cold int tiff_init(AVCodecContext *avctx){
Kostya Shishkov's avatar
Kostya Shishkov committed
619 620 621 622 623
    TiffContext *s = avctx->priv_data;

    s->width = 0;
    s->height = 0;
    s->avctx = avctx;
624 625
    avcodec_get_frame_defaults(&s->picture);
    avctx->coded_frame = &s->picture;
626
    ff_lzw_decode_open(&s->lzw);
Michael Niedermayer's avatar
Michael Niedermayer committed
627
    ff_ccitt_unpack_init();
Kostya Shishkov's avatar
Kostya Shishkov committed
628 629 630 631

    return 0;
}

632
static av_cold int tiff_end(AVCodecContext *avctx)
Kostya Shishkov's avatar
Kostya Shishkov committed
633 634 635
{
    TiffContext * const s = avctx->priv_data;

636
    ff_lzw_decode_close(&s->lzw);
Kostya Shishkov's avatar
Kostya Shishkov committed
637 638 639 640 641
    if(s->picture.data[0])
        avctx->release_buffer(avctx, &s->picture);
    return 0;
}

642
AVCodec ff_tiff_decoder = {
643 644 645 646 647 648 649 650
    .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,
651
    .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
Kostya Shishkov's avatar
Kostya Shishkov committed
652
};