Browse code

tiff encoder by (Bartlomiej Wolowiec b.wolowiec students mimuw edu pl)

Originally committed as revision 8608 to svn://svn.ffmpeg.org/ffmpeg/trunk

Michael Niedermayer authored on 2007/04/03 22:43:57
Showing 8 changed files
... ...
@@ -63,7 +63,7 @@ version <next>
63 63
 - Delphine Software .cin demuxer/audio and video decoder
64 64
 - Tiertex .seq demuxer/video decoder
65 65
 - MTV demuxer
66
-- TIFF picture decoder
66
+- TIFF picture encoder and decoder
67 67
 - GIF picture decoder
68 68
 - Intel Music decoder
69 69
 - Musepack decoder
... ...
@@ -922,7 +922,7 @@ following image formats are supported:
922 922
 @item animated GIF @tab X @tab X @tab Only uncompressed GIFs are generated.
923 923
 @item PNG          @tab X @tab X @tab 2 bit and 4 bit/pixel not supported yet.
924 924
 @item Targa        @tab   @tab X @tab Targa (.TGA) image format.
925
-@item TIFF         @tab   @tab X @tab Only 24 bit/pixel images are supported.
925
+@item TIFF         @tab X @tab X @tab YUV, JPEG and some extension is not supported yet.
926 926
 @item SGI          @tab X @tab X @tab SGI RGB image format
927 927
 @end multitable
928 928
 
... ...
@@ -144,6 +144,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)           += targaenc.o rle.o
144 144
 OBJS-$(CONFIG_THEORA_DECODER)          += vp3.o xiph.o
145 145
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
146 146
 OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o
147
+OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o
147 148
 OBJS-$(CONFIG_TRUEMOTION1_DECODER)     += truemotion1.o
148 149
 OBJS-$(CONFIG_TRUEMOTION2_DECODER)     += truemotion2.o
149 150
 OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
... ...
@@ -132,7 +132,7 @@ void avcodec_register_all(void)
132 132
     REGISTER_DECODER(THEORA, theora);
133 133
     REGISTER_DECODER(THP, thp);
134 134
     REGISTER_DECODER(TIERTEXSEQVIDEO, tiertexseqvideo);
135
-    REGISTER_DECODER(TIFF, tiff);
135
+    REGISTER_ENCDEC (TIFF, tiff);
136 136
     REGISTER_DECODER(TRUEMOTION1, truemotion1);
137 137
     REGISTER_DECODER(TRUEMOTION2, truemotion2);
138 138
     REGISTER_DECODER(TSCC, tscc);
... ...
@@ -2222,6 +2222,7 @@ extern AVCodec sonic_encoder;
2222 2222
 extern AVCodec sonic_ls_encoder;
2223 2223
 extern AVCodec svq1_encoder;
2224 2224
 extern AVCodec targa_encoder;
2225
+extern AVCodec tiff_encoder;
2225 2226
 extern AVCodec vcr1_encoder;
2226 2227
 extern AVCodec vorbis_encoder;
2227 2228
 extern AVCodec wmav1_encoder;
... ...
@@ -24,49 +24,8 @@
24 24
 #include <zlib.h>
25 25
 #endif
26 26
 #include "lzw.h"
27
+#include "tiff.h"
27 28
 
28
-/* abridged list of TIFF tags */
29
-enum TiffTags{
30
-    TIFF_WIDTH = 0x100,
31
-    TIFF_HEIGHT,
32
-    TIFF_BPP,
33
-    TIFF_COMPR,
34
-    TIFF_INVERT = 0x106,
35
-    TIFF_STRIP_OFFS = 0x111,
36
-    TIFF_ROWSPERSTRIP = 0x116,
37
-    TIFF_STRIP_SIZE,
38
-    TIFF_PLANAR = 0x11C,
39
-    TIFF_XPOS = 0x11E,
40
-    TIFF_YPOS = 0x11F,
41
-    TIFF_PREDICTOR = 0x13D,
42
-    TIFF_PAL = 0x140
43
-};
44
-
45
-enum TiffCompr{
46
-    TIFF_RAW = 1,
47
-    TIFF_CCITT_RLE,
48
-    TIFF_G3,
49
-    TIFF_G4,
50
-    TIFF_LZW,
51
-    TIFF_JPEG,
52
-    TIFF_NEWJPEG,
53
-    TIFF_ADOBE_DEFLATE,
54
-    TIFF_PACKBITS = 0x8005,
55
-    TIFF_DEFLATE = 0x80B2
56
-};
57
-
58
-enum TiffTypes{
59
-    TIFF_BYTE = 1,
60
-    TIFF_STRING,
61
-    TIFF_SHORT,
62
-    TIFF_LONG,
63
-    TIFF_LONGLONG
64
-};
65
-
66
-/** sizes of various TIFF field types */
67
-static const int type_sizes[6] = {
68
-    0, 1, 100, 2, 4, 8
69
-};
70 29
 
71 30
 typedef struct TiffContext {
72 31
     AVCodecContext *avctx;
73 32
new file mode 100644
... ...
@@ -0,0 +1,79 @@
0
+/*
1
+ * TIFF tables
2
+ * Copyright (c) 2006 Konstantin Shishkov
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ *
20
+ */
21
+
22
+#ifndef TIFF_H
23
+#define TIFF_H
24
+
25
+/* abridged list of TIFF tags */
26
+enum TiffTags{
27
+    TIFF_SUBFILE = 0xfe,
28
+    TIFF_WIDTH = 0x100,
29
+    TIFF_HEIGHT,
30
+    TIFF_BPP,
31
+    TIFF_COMPR,
32
+    TIFF_INVERT = 0x106,
33
+    TIFF_STRIP_OFFS = 0x111,
34
+    TIFF_SAMPLES_PER_PIXEL = 0x115,
35
+    TIFF_ROWSPERSTRIP = 0x116,
36
+    TIFF_STRIP_SIZE,
37
+    TIFF_XRES = 0x11A,
38
+    TIFF_YRES = 0x11B,
39
+    TIFF_PLANAR = 0x11C,
40
+    TIFF_XPOS = 0x11E,
41
+    TIFF_YPOS = 0x11F,
42
+    TIFF_RES_UNIT = 0x128,
43
+    TIFF_SOFTWARE_NAME = 0x131,
44
+    TIFF_PREDICTOR = 0x13D,
45
+    TIFF_PAL = 0x140,
46
+    TIFF_YCBCR_COEFFICIENTS = 0x211,
47
+    TIFF_YCBCR_SUBSAMPLING = 0x212,
48
+    TIFF_YCBCR_POSITIONING = 0x213,
49
+    TIFF_REFERENCE_BW = 0x214,
50
+};
51
+
52
+enum TiffCompr{
53
+    TIFF_RAW = 1,
54
+    TIFF_CCITT_RLE,
55
+    TIFF_G3,
56
+    TIFF_G4,
57
+    TIFF_LZW,
58
+    TIFF_JPEG,
59
+    TIFF_NEWJPEG,
60
+    TIFF_ADOBE_DEFLATE,
61
+    TIFF_PACKBITS = 0x8005,
62
+    TIFF_DEFLATE = 0x80B2
63
+};
64
+
65
+enum TiffTypes{
66
+    TIFF_BYTE = 1,
67
+    TIFF_STRING,
68
+    TIFF_SHORT,
69
+    TIFF_LONG,
70
+    TIFF_RATIONAL,
71
+};
72
+
73
+/** sizes of various TIFF field types (string size = 100)*/
74
+static const uint8_t type_sizes[6] = {
75
+    0, 1, 100, 2, 4, 8
76
+};
77
+
78
+#endif                          /* TIFF_H */
0 79
new file mode 100644
... ...
@@ -0,0 +1,359 @@
0
+/*
1
+ * TIFF image encoder
2
+ * Copyright (c) 2007 Bartlomiej Wolowiec
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ *
20
+ */
21
+
22
+#include "avcodec.h"
23
+#ifdef CONFIG_ZLIB
24
+#include <zlib.h>
25
+#endif
26
+#include "bytestream.h"
27
+#include "tiff.h"
28
+#include "rle.h"
29
+
30
+#define TIFF_MAX_ENTRY 32
31
+
32
+/** sizes of various TIFF field types (string size = 1)*/
33
+static const uint8_t type_sizes2[6] = {
34
+    0, 1, 1, 2, 4, 8
35
+};
36
+
37
+typedef struct TiffEncoderContext {
38
+    AVCodecContext *avctx;
39
+    AVFrame picture;
40
+
41
+    int width;                          ///< picture width
42
+    int height;                         ///< picture height
43
+    unsigned int bpp;                   ///< bits per pixel
44
+    int compr;                          ///< compression level
45
+    int bpp_tab_size;                   ///< bpp_tab size
46
+    int invert;                         ///< photometric interpretation
47
+    int strips;                         ///< number of strips
48
+    int rps;                            ///< row per strip
49
+    uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
50
+    int num_entries;                    ///< number of entires
51
+    uint8_t **buf;                      ///< actual position in buffer
52
+    uint8_t *buf_start;                 ///< pointer to first byte in buffer
53
+    int buf_size;                       ///< buffer size
54
+} TiffEncoderContext;
55
+
56
+
57
+/**
58
+ * Check free space in buffer
59
+ * @param s Tiff context
60
+ * @param need Needed bytes
61
+ * @return 0 - ok, 1 - no free space
62
+ */
63
+inline static int check_size(TiffEncoderContext * s, uint64_t need)
64
+{
65
+    if (s->buf_size < *s->buf - s->buf_start + need) {
66
+        *s->buf = s->buf_start + s->buf_size + 1;
67
+        av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n");
68
+        return 1;
69
+    }
70
+    return 0;
71
+}
72
+
73
+/**
74
+ * Put n values to buffer
75
+ *
76
+ * @param p Pointer to pointer to output buffer
77
+ * @param n Number of values
78
+ * @param val Pointer to values
79
+ * @param type Type of values
80
+ * @param flip =0 - normal copy, >0 - flip
81
+ */
82
+static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
83
+                  int flip)
84
+{
85
+    int i;
86
+#ifdef WORDS_BIGENDIAN
87
+    flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
88
+#endif
89
+    for (i = 0; i < n * type_sizes2[type]; i++)
90
+        *(*p)++ = val[i ^ flip];
91
+}
92
+
93
+/**
94
+ * Add entry to directory in tiff header.
95
+ * @param s Tiff context
96
+ * @param tag Tag that identifies the entry
97
+ * @param type Entry type
98
+ * @param count The number of values
99
+ * @param ptr_val Pointer to values
100
+ */
101
+static void add_entry(TiffEncoderContext * s,
102
+                      enum TiffTags tag, enum TiffTypes type, int count,
103
+                      const void *ptr_val)
104
+{
105
+    uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
106
+
107
+    assert(s->num_entries < TIFF_MAX_ENTRY);
108
+
109
+    bytestream_put_le16(&entries_ptr, tag);
110
+    bytestream_put_le16(&entries_ptr, type);
111
+    bytestream_put_le32(&entries_ptr, count);
112
+
113
+    if (type_sizes[type] * count <= 4) {
114
+        tnput(&entries_ptr, count, ptr_val, type, 0);
115
+    } else {
116
+        bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
117
+        check_size(s, count * type_sizes2[type]);
118
+        tnput(s->buf, count, ptr_val, type, 0);
119
+    }
120
+
121
+    s->num_entries++;
122
+}
123
+
124
+/**
125
+ * Encode one strip in tiff file
126
+ *
127
+ * @param s Tiff context
128
+ * @param src Input buffer
129
+ * @param dst Output buffer
130
+ * @param n Size of input buffer
131
+ * @param compr Compression method
132
+ * @return Number of output bytes. If an output error is encountered, -1 returned
133
+ */
134
+static int encode_strip(TiffEncoderContext * s, const int8_t * src,
135
+                        uint8_t * dst, int n, int compr)
136
+{
137
+
138
+    switch (compr) {
139
+#ifdef CONFIG_ZLIB
140
+    case TIFF_DEFLATE:
141
+    case TIFF_ADOBE_DEFLATE:
142
+        {
143
+            unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
144
+            if (compress(dst, &zlen, src, n) != Z_OK) {
145
+                av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
146
+                return -1;
147
+            }
148
+            return zlen;
149
+        }
150
+#endif
151
+    case TIFF_RAW:
152
+        if (check_size(s, n))
153
+            return -1;
154
+        memcpy(dst, src, n);
155
+        return n;
156
+    case TIFF_PACKBITS:
157
+        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
158
+    default:
159
+        return -1;
160
+    }
161
+}
162
+
163
+static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
164
+                        int buf_size, void *data)
165
+{
166
+    TiffEncoderContext *s = avctx->priv_data;
167
+    AVFrame *pict = data;
168
+    AVFrame *const p = (AVFrame *) & s->picture;
169
+    int i;
170
+    int n;
171
+    uint8_t *ptr = buf;
172
+    uint8_t *offset;
173
+    uint32_t strips;
174
+    uint32_t *strip_sizes = NULL;
175
+    uint32_t *strip_offsets = NULL;
176
+    int bytes_per_row;
177
+    uint32_t res[2] = { 72, 1 };        // image resolution (72/1)
178
+    static const uint16_t bpp_tab[] = { 8, 8, 8, 8 };
179
+    int ret = -1;
180
+
181
+    s->buf_start = buf;
182
+    s->buf = &ptr;
183
+    s->buf_size = buf_size;
184
+
185
+    *p = *pict;
186
+    p->pict_type = FF_I_TYPE;
187
+    p->key_frame = 1;
188
+
189
+    s->compr = TIFF_PACKBITS;
190
+    if (avctx->compression_level == 0) {
191
+        s->compr = TIFF_RAW;
192
+#ifdef CONFIG_ZLIB
193
+    } else if ((avctx->compression_level > 2)) {
194
+        s->compr = TIFF_DEFLATE;
195
+#endif
196
+    }
197
+
198
+    s->width = avctx->width;
199
+    s->height = avctx->height;
200
+
201
+    switch (avctx->pix_fmt) {
202
+    case PIX_FMT_RGB24:
203
+        s->bpp = 24;
204
+        s->invert = 2;
205
+        break;
206
+    case PIX_FMT_GRAY8:
207
+        s->bpp = 8;
208
+        s->invert = 1;
209
+        break;
210
+    case PIX_FMT_PAL8:
211
+        s->bpp = 8;
212
+        s->invert = 3;
213
+        break;
214
+    case PIX_FMT_MONOBLACK:
215
+        s->bpp = 1;
216
+        s->invert = 1;
217
+        break;
218
+    case PIX_FMT_MONOWHITE:
219
+        s->bpp = 1;
220
+        s->invert = 0;
221
+        break;
222
+    default:
223
+        av_log(s->avctx, AV_LOG_ERROR,
224
+               "This colors format is not supported\n");
225
+        return -1;
226
+    }
227
+    s->bpp_tab_size = (s->bpp >> 3);
228
+
229
+    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE)
230
+        //best choose for DEFLATE
231
+        s->rps = s->height;
232
+    else
233
+        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
234
+
235
+    strips = (s->height - 1) / s->rps + 1;
236
+
237
+    if (check_size(s, 8))
238
+        goto fail;
239
+
240
+    // write header
241
+    bytestream_put_le16(&ptr, 0x4949);
242
+    bytestream_put_le16(&ptr, 42);
243
+
244
+    offset = ptr;
245
+    bytestream_put_le32(&ptr, 0);
246
+
247
+    strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);
248
+    strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
249
+
250
+    bytes_per_row = (s->width * s->bpp + 7) >> 3;
251
+
252
+#ifdef CONFIG_ZLIB
253
+    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
254
+        uint8_t *zbuf;
255
+        int zlen, zn;
256
+        int j;
257
+
258
+        zlen = bytes_per_row * s->rps;
259
+        zbuf = av_malloc(zlen);
260
+        strip_offsets[0] = ptr - buf;
261
+        zn = 0;
262
+        for (j = 0; j < s->rps; j++) {
263
+            memcpy(zbuf + j * bytes_per_row,
264
+                   p->data[0] + j * p->linesize[0], bytes_per_row);
265
+            zn += bytes_per_row;
266
+        }
267
+        n = encode_strip(s, zbuf, ptr, zn, s->compr);
268
+        av_free(zbuf);
269
+        if (n<0) {
270
+            av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
271
+            goto fail;
272
+        }
273
+        ptr += n;
274
+        strip_sizes[0] = ptr - buf - strip_offsets[0];
275
+    } else
276
+#endif
277
+    {
278
+        for (i = 0; i < s->height; i++) {
279
+            if (strip_sizes[i / s->rps] == 0) {
280
+                strip_offsets[i / s->rps] = ptr - buf;
281
+            }
282
+            if ((n = encode_strip(s, p->data[0] + i * p->linesize[0]
283
+                                  , ptr, bytes_per_row, s->compr)) < 0) {
284
+                av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
285
+                goto fail;
286
+            }
287
+            strip_sizes[i / s->rps] += n;
288
+            ptr += n;
289
+        }
290
+    }
291
+
292
+    s->num_entries = 0;
293
+
294
+    add_entry(s, TIFF_SUBFILE,           TIFF_LONG,     1,      (uint32_t[]) {0});
295
+    add_entry(s, TIFF_WIDTH,             TIFF_LONG,     1,      (uint32_t[]) {s->width});
296
+    add_entry(s, TIFF_HEIGHT,            TIFF_LONG,     1,      (uint32_t[]) {s->height});
297
+
298
+    if (s->bpp_tab_size)
299
+    add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
300
+
301
+    add_entry(s, TIFF_COMPR,             TIFF_SHORT,    1,      (uint16_t[]) {s->compr});
302
+    add_entry(s, TIFF_INVERT,            TIFF_SHORT,    1,      (uint16_t[]) {s->invert});
303
+    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);
304
+
305
+    if (s->bpp_tab_size)
306
+    add_entry(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,    1,      (uint16_t[]) {s->bpp_tab_size});
307
+
308
+    add_entry(s, TIFF_ROWSPERSTRIP,      TIFF_LONG,     1,      (uint32_t[]) {s->rps});
309
+    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);
310
+    add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
311
+    add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
312
+    add_entry(s, TIFF_RES_UNIT,          TIFF_SHORT,    1,      (uint16_t[]) {2});
313
+    add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
314
+              strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
315
+
316
+    if (avctx->pix_fmt == PIX_FMT_PAL8) {
317
+        uint16_t pal[256 * 3];
318
+        for (i = 0; i < 256; i++) {
319
+            uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
320
+            pal[i]       = ((rgb >> 16) & 0xff) * 257;
321
+            pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
322
+            pal[i + 512] = ( rgb        & 0xff) * 257;
323
+        }
324
+        add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
325
+    }
326
+    bytestream_put_le32(&offset, ptr - buf);    // write offset to dir
327
+
328
+    if (check_size(s, 6 + s->num_entries * 12))
329
+        goto fail;
330
+    bytestream_put_le16(&ptr, s->num_entries);  // write tag count
331
+    bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);
332
+    bytestream_put_le32(&ptr, 0);
333
+
334
+    ret = ptr - buf;
335
+
336
+fail:
337
+    av_free(strip_sizes);
338
+    av_free(strip_offsets);
339
+    return ret;
340
+}
341
+
342
+AVCodec tiff_encoder = {
343
+    "tiff",
344
+    CODEC_TYPE_VIDEO,
345
+    CODEC_ID_TIFF,
346
+    sizeof(TiffEncoderContext),
347
+    NULL,
348
+    encode_frame,
349
+    NULL,
350
+    NULL,
351
+    0,
352
+    NULL,
353
+    .pix_fmts =
354
+        (enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8,
355
+                              PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,
356
+                              -1}
357
+
358
+};