~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/tiffenc.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc, Andrew Starr-Bochicchio, Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081226001006-2040ls9680bd1blt
Tags: 1.1.7-0.2ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian-multimedia (LP: #298547), Ubuntu Changes:
 - For ffmpeg-related build-deps, fix versionized dependencies
   as the ubuntu versioning is different than debian-multimedia's.

[ Lionel Le Folgoc ]
* LP: #311412 is fixed since the 1.1.7~rc1-0.1 revision.
* debian/patches/03_ffmpeg.diff: updated to fix FTBFS due to libswscale API
  change (cherry-pick from Gentoo #234383).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * TIFF image encoder
 
3
 * Copyright (c) 2007 Bartlomiej Wolowiec
 
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
 
 
22
/**
 
23
 * TIFF image encoder
 
24
 * @file tiffenc.c
 
25
 * @author Bartlomiej Wolowiec
 
26
 */
 
27
#include "avcodec.h"
 
28
#ifdef CONFIG_ZLIB
 
29
#include <zlib.h>
 
30
#endif
 
31
#include "bytestream.h"
 
32
#include "tiff.h"
 
33
#include "rle.h"
 
34
#include "lzw.h"
 
35
 
 
36
#define TIFF_MAX_ENTRY 32
 
37
 
 
38
/** sizes of various TIFF field types (string size = 1)*/
 
39
static const uint8_t type_sizes2[6] = {
 
40
    0, 1, 1, 2, 4, 8
 
41
};
 
42
 
 
43
typedef struct TiffEncoderContext {
 
44
    AVCodecContext *avctx;
 
45
    AVFrame picture;
 
46
 
 
47
    int width;                          ///< picture width
 
48
    int height;                         ///< picture height
 
49
    unsigned int bpp;                   ///< bits per pixel
 
50
    int compr;                          ///< compression level
 
51
    int bpp_tab_size;                   ///< bpp_tab size
 
52
    int photometric_interpretation;     ///< photometric interpretation
 
53
    int strips;                         ///< number of strips
 
54
    int rps;                            ///< row per strip
 
55
    uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
 
56
    int num_entries;                    ///< number of entires
 
57
    uint8_t **buf;                      ///< actual position in buffer
 
58
    uint8_t *buf_start;                 ///< pointer to first byte in buffer
 
59
    int buf_size;                       ///< buffer size
 
60
    uint16_t subsampling[2];            ///< YUV subsampling factors
 
61
    struct LZWEncodeState *lzws;        ///< LZW Encode state
 
62
} TiffEncoderContext;
 
63
 
 
64
 
 
65
/**
 
66
 * Check free space in buffer
 
67
 * @param s Tiff context
 
68
 * @param need Needed bytes
 
69
 * @return 0 - ok, 1 - no free space
 
70
 */
 
71
inline static int check_size(TiffEncoderContext * s, uint64_t need)
 
72
{
 
73
    if (s->buf_size < *s->buf - s->buf_start + need) {
 
74
        *s->buf = s->buf_start + s->buf_size + 1;
 
75
        av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n");
 
76
        return 1;
 
77
    }
 
78
    return 0;
 
79
}
 
80
 
 
81
/**
 
82
 * Put n values to buffer
 
83
 *
 
84
 * @param p Pointer to pointer to output buffer
 
85
 * @param n Number of values
 
86
 * @param val Pointer to values
 
87
 * @param type Type of values
 
88
 * @param flip =0 - normal copy, >0 - flip
 
89
 */
 
90
static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
 
91
                  int flip)
 
92
{
 
93
    int i;
 
94
#ifdef WORDS_BIGENDIAN
 
95
    flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
 
96
#endif
 
97
    for (i = 0; i < n * type_sizes2[type]; i++)
 
98
        *(*p)++ = val[i ^ flip];
 
99
}
 
100
 
 
101
/**
 
102
 * Add entry to directory in tiff header.
 
103
 * @param s Tiff context
 
104
 * @param tag Tag that identifies the entry
 
105
 * @param type Entry type
 
106
 * @param count The number of values
 
107
 * @param ptr_val Pointer to values
 
108
 */
 
109
static void add_entry(TiffEncoderContext * s,
 
110
                      enum TiffTags tag, enum TiffTypes type, int count,
 
111
                      const void *ptr_val)
 
112
{
 
113
    uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
 
114
 
 
115
    assert(s->num_entries < TIFF_MAX_ENTRY);
 
116
 
 
117
    bytestream_put_le16(&entries_ptr, tag);
 
118
    bytestream_put_le16(&entries_ptr, type);
 
119
    bytestream_put_le32(&entries_ptr, count);
 
120
 
 
121
    if (type_sizes[type] * count <= 4) {
 
122
        tnput(&entries_ptr, count, ptr_val, type, 0);
 
123
    } else {
 
124
        bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
 
125
        check_size(s, count * type_sizes2[type]);
 
126
        tnput(s->buf, count, ptr_val, type, 0);
 
127
    }
 
128
 
 
129
    s->num_entries++;
 
130
}
 
131
 
 
132
static void add_entry1(TiffEncoderContext * s,
 
133
                       enum TiffTags tag, enum TiffTypes type, int val){
 
134
    uint16_t w = val;
 
135
    uint32_t dw= val;
 
136
    add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw);
 
137
}
 
138
 
 
139
/**
 
140
 * Encode one strip in tiff file
 
141
 *
 
142
 * @param s Tiff context
 
143
 * @param src Input buffer
 
144
 * @param dst Output buffer
 
145
 * @param n Size of input buffer
 
146
 * @param compr Compression method
 
147
 * @return Number of output bytes. If an output error is encountered, -1 returned
 
148
 */
 
149
static int encode_strip(TiffEncoderContext * s, const int8_t * src,
 
150
                        uint8_t * dst, int n, int compr)
 
151
{
 
152
 
 
153
    switch (compr) {
 
154
#ifdef CONFIG_ZLIB
 
155
    case TIFF_DEFLATE:
 
156
    case TIFF_ADOBE_DEFLATE:
 
157
        {
 
158
            unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
 
159
            if (compress(dst, &zlen, src, n) != Z_OK) {
 
160
                av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
 
161
                return -1;
 
162
            }
 
163
            return zlen;
 
164
        }
 
165
#endif
 
166
    case TIFF_RAW:
 
167
        if (check_size(s, n))
 
168
            return -1;
 
169
        memcpy(dst, src, n);
 
170
        return n;
 
171
    case TIFF_PACKBITS:
 
172
        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
 
173
    case TIFF_LZW:
 
174
        return ff_lzw_encode(s->lzws, src, n);
 
175
    default:
 
176
        return -1;
 
177
    }
 
178
}
 
179
 
 
180
static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
 
181
{
 
182
    AVFrame *p = &s->picture;
 
183
    int i, j, k;
 
184
    int w = (s->width - 1) / s->subsampling[0] + 1;
 
185
    uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
 
186
    uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
 
187
    for (i = 0; i < w; i++){
 
188
        for (j = 0; j < s->subsampling[1]; j++)
 
189
            for (k = 0; k < s->subsampling[0]; k++)
 
190
                *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
 
191
                                    i * s->subsampling[0] + k];
 
192
        *dst++ = *pu++;
 
193
        *dst++ = *pv++;
 
194
    }
 
195
}
 
196
 
 
197
static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
 
198
                        int buf_size, void *data)
 
199
{
 
200
    TiffEncoderContext *s = avctx->priv_data;
 
201
    AVFrame *pict = data;
 
202
    AVFrame *const p = (AVFrame *) & s->picture;
 
203
    int i;
 
204
    int n;
 
205
    uint8_t *ptr = buf;
 
206
    uint8_t *offset;
 
207
    uint32_t strips;
 
208
    uint32_t *strip_sizes = NULL;
 
209
    uint32_t *strip_offsets = NULL;
 
210
    int bytes_per_row;
 
211
    uint32_t res[2] = { 72, 1 };        // image resolution (72/1)
 
212
    static const uint16_t bpp_tab[] = { 8, 8, 8, 8 };
 
213
    int ret = -1;
 
214
    int is_yuv = 0;
 
215
    uint8_t *yuv_line = NULL;
 
216
    int shift_h, shift_v;
 
217
 
 
218
    s->buf_start = buf;
 
219
    s->buf = &ptr;
 
220
    s->buf_size = buf_size;
 
221
 
 
222
    *p = *pict;
 
223
    p->pict_type = FF_I_TYPE;
 
224
    p->key_frame = 1;
 
225
 
 
226
    s->compr = TIFF_PACKBITS;
 
227
    if (avctx->compression_level == 0) {
 
228
        s->compr = TIFF_RAW;
 
229
    } else if(avctx->compression_level == 2) {
 
230
        s->compr = TIFF_LZW;
 
231
#ifdef CONFIG_ZLIB
 
232
    } else if ((avctx->compression_level >= 3)) {
 
233
        s->compr = TIFF_DEFLATE;
 
234
#endif
 
235
    }
 
236
 
 
237
    s->width = avctx->width;
 
238
    s->height = avctx->height;
 
239
    s->subsampling[0] = 1;
 
240
    s->subsampling[1] = 1;
 
241
 
 
242
    switch (avctx->pix_fmt) {
 
243
    case PIX_FMT_RGB24:
 
244
        s->bpp = 24;
 
245
        s->photometric_interpretation = 2;
 
246
        break;
 
247
    case PIX_FMT_GRAY8:
 
248
        s->bpp = 8;
 
249
        s->photometric_interpretation = 1;
 
250
        break;
 
251
    case PIX_FMT_PAL8:
 
252
        s->bpp = 8;
 
253
        s->photometric_interpretation = 3;
 
254
        break;
 
255
    case PIX_FMT_MONOBLACK:
 
256
        s->bpp = 1;
 
257
        s->photometric_interpretation = 1;
 
258
        break;
 
259
    case PIX_FMT_MONOWHITE:
 
260
        s->bpp = 1;
 
261
        s->photometric_interpretation = 0;
 
262
        break;
 
263
    case PIX_FMT_YUV420P:
 
264
    case PIX_FMT_YUV422P:
 
265
    case PIX_FMT_YUV444P:
 
266
    case PIX_FMT_YUV410P:
 
267
    case PIX_FMT_YUV411P:
 
268
        s->photometric_interpretation = 6;
 
269
        avcodec_get_chroma_sub_sample(avctx->pix_fmt,
 
270
                &shift_h, &shift_v);
 
271
        s->bpp = 8 + (16 >> (shift_h + shift_v));
 
272
        s->subsampling[0] = 1 << shift_h;
 
273
        s->subsampling[1] = 1 << shift_v;
 
274
        s->bpp_tab_size = 3;
 
275
        is_yuv = 1;
 
276
        break;
 
277
    default:
 
278
        av_log(s->avctx, AV_LOG_ERROR,
 
279
               "This colors format is not supported\n");
 
280
        return -1;
 
281
    }
 
282
    if (!is_yuv)
 
283
        s->bpp_tab_size = (s->bpp >> 3);
 
284
 
 
285
    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
 
286
        //best choose for DEFLATE
 
287
        s->rps = s->height;
 
288
    else
 
289
        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
 
290
    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
 
291
 
 
292
    strips = (s->height - 1) / s->rps + 1;
 
293
 
 
294
    if (check_size(s, 8))
 
295
        goto fail;
 
296
 
 
297
    // write header
 
298
    bytestream_put_le16(&ptr, 0x4949);
 
299
    bytestream_put_le16(&ptr, 42);
 
300
 
 
301
    offset = ptr;
 
302
    bytestream_put_le32(&ptr, 0);
 
303
 
 
304
    strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);
 
305
    strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
 
306
 
 
307
    bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
 
308
                    * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
 
309
    if (is_yuv){
 
310
        yuv_line = av_malloc(bytes_per_row);
 
311
        if (yuv_line == NULL){
 
312
            av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
 
313
            goto fail;
 
314
        }
 
315
    }
 
316
 
 
317
#ifdef CONFIG_ZLIB
 
318
    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
 
319
        uint8_t *zbuf;
 
320
        int zlen, zn;
 
321
        int j;
 
322
 
 
323
        zlen = bytes_per_row * s->rps;
 
324
        zbuf = av_malloc(zlen);
 
325
        strip_offsets[0] = ptr - buf;
 
326
        zn = 0;
 
327
        for (j = 0; j < s->rps; j++) {
 
328
            if (is_yuv){
 
329
                pack_yuv(s, yuv_line, j);
 
330
                memcpy(zbuf + zn, yuv_line, bytes_per_row);
 
331
                j += s->subsampling[1] - 1;
 
332
            }
 
333
            else
 
334
                memcpy(zbuf + j * bytes_per_row,
 
335
                       p->data[0] + j * p->linesize[0], bytes_per_row);
 
336
            zn += bytes_per_row;
 
337
        }
 
338
        n = encode_strip(s, zbuf, ptr, zn, s->compr);
 
339
        av_free(zbuf);
 
340
        if (n<0) {
 
341
            av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
 
342
            goto fail;
 
343
        }
 
344
        ptr += n;
 
345
        strip_sizes[0] = ptr - buf - strip_offsets[0];
 
346
    } else
 
347
#endif
 
348
    {
 
349
        if(s->compr == TIFF_LZW)
 
350
            s->lzws = av_malloc(ff_lzw_encode_state_size);
 
351
        for (i = 0; i < s->height; i++) {
 
352
            if (strip_sizes[i / s->rps] == 0) {
 
353
                if(s->compr == TIFF_LZW){
 
354
                    ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start), 12);
 
355
                }
 
356
                strip_offsets[i / s->rps] = ptr - buf;
 
357
            }
 
358
            if (is_yuv){
 
359
                 pack_yuv(s, yuv_line, i);
 
360
                 n = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
 
361
                 i += s->subsampling[1] - 1;
 
362
            }
 
363
            else
 
364
                n = encode_strip(s, p->data[0] + i * p->linesize[0],
 
365
                        ptr, bytes_per_row, s->compr);
 
366
            if (n < 0) {
 
367
                av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
 
368
                goto fail;
 
369
            }
 
370
            strip_sizes[i / s->rps] += n;
 
371
            ptr += n;
 
372
            if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
 
373
                int ret;
 
374
                ret = ff_lzw_encode_flush(s->lzws);
 
375
                strip_sizes[(i / s->rps )] += ret ;
 
376
                ptr += ret;
 
377
            }
 
378
        }
 
379
        if(s->compr == TIFF_LZW)
 
380
            av_free(s->lzws);
 
381
    }
 
382
 
 
383
    s->num_entries = 0;
 
384
 
 
385
    add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);
 
386
    add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);
 
387
    add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);
 
388
 
 
389
    if (s->bpp_tab_size)
 
390
    add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
 
391
 
 
392
    add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
 
393
    add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
 
394
    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);
 
395
 
 
396
    if (s->bpp_tab_size)
 
397
    add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
 
398
 
 
399
    add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
 
400
    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);
 
401
    add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
 
402
    add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
 
403
    add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
 
404
 
 
405
    if(!(avctx->flags & CODEC_FLAG_BITEXACT))
 
406
    add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
 
407
              strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
 
408
 
 
409
    if (avctx->pix_fmt == PIX_FMT_PAL8) {
 
410
        uint16_t pal[256 * 3];
 
411
        for (i = 0; i < 256; i++) {
 
412
            uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
 
413
            pal[i]       = ((rgb >> 16) & 0xff) * 257;
 
414
            pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
 
415
            pal[i + 512] = ( rgb        & 0xff) * 257;
 
416
        }
 
417
        add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
 
418
    }
 
419
    if (is_yuv){
 
420
        /** according to CCIR Recommendation 601.1 */
 
421
        uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
 
422
        add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
 
423
        add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
 
424
    }
 
425
    bytestream_put_le32(&offset, ptr - buf);    // write offset to dir
 
426
 
 
427
    if (check_size(s, 6 + s->num_entries * 12))
 
428
        goto fail;
 
429
    bytestream_put_le16(&ptr, s->num_entries);  // write tag count
 
430
    bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);
 
431
    bytestream_put_le32(&ptr, 0);
 
432
 
 
433
    ret = ptr - buf;
 
434
 
 
435
fail:
 
436
    av_free(strip_sizes);
 
437
    av_free(strip_offsets);
 
438
    av_free(yuv_line);
 
439
    return ret;
 
440
}
 
441
 
 
442
AVCodec tiff_encoder = {
 
443
    "tiff",
 
444
    CODEC_TYPE_VIDEO,
 
445
    CODEC_ID_TIFF,
 
446
    sizeof(TiffEncoderContext),
 
447
    NULL,
 
448
    encode_frame,
 
449
    NULL,
 
450
    NULL,
 
451
    0,
 
452
    NULL,
 
453
    .pix_fmts =
 
454
        (enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8,
 
455
                              PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,
 
456
                              PIX_FMT_YUV420P, PIX_FMT_YUV422P,
 
457
                              PIX_FMT_YUV444P, PIX_FMT_YUV410P,
 
458
                              PIX_FMT_YUV411P,
 
459
                              -1},
 
460
    .long_name = "TIFF image",
 
461
};