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 * @file
24 * TIFF image encoder
25 * @author Bartlomiej Wolowiec
26 */
27
28 #include "config.h"
29 #if CONFIG_ZLIB
30 #include <zlib.h>
31 #endif
32
46
47 #define TIFF_MAX_ENTRY 32
48
49 /** sizes of various TIFF field types (string size = 1)*/
51 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
52 };
53
57
60 unsigned int bpp;
///< bits per pixel
61 int compr;
///< compression level
71 int rps;
///< row per strip
74 uint8_t **
buf;
///< actual position in buffer
75 uint8_t *
buf_start;
///< pointer to first byte in buffer
79 uint32_t
dpi;
///< image resolution in DPI
81
82 /**
83 * Check free space in buffer.
84 *
85 * @param s Tiff context
86 * @param need Needed bytes
87 * @return 0 - ok, 1 - no free space
88 */
90 {
91 if (
s->buf_size < *
s->buf -
s->buf_start +
need) {
92 *
s->buf =
s->buf_start +
s->buf_size + 1;
94 return 1;
95 }
96 return 0;
97 }
98
99 /**
100 * Put n values to buffer.
101 *
102 * @param p pointer to pointer to output buffer
103 * @param n number of values
104 * @param val pointer to values
105 * @param type type of values
106 * @param flip = 0 - normal copy, >0 - flip
107 */
110 {
112 #if HAVE_BIGENDIAN
113 flip ^= ((
int[]) { 0, 0, 0, 1, 3, 3 })[
type];
114 #endif
117 }
118
119 /**
120 * Add entry to directory in tiff header.
121 *
122 * @param s Tiff context
123 * @param tag tag that identifies the entry
124 * @param type entry type
125 * @param count the number of values
126 * @param ptr_val pointer to values
127 */
130 {
131 uint8_t *entries_ptr =
s->entries + 12 *
s->num_entries;
132
134
135 bytestream_put_le16(&entries_ptr,
tag);
136 bytestream_put_le16(&entries_ptr,
type);
137 bytestream_put_le32(&entries_ptr, count);
138
140 tnput(&entries_ptr, count, ptr_val,
type, 0);
141 } else {
142 bytestream_put_le32(&entries_ptr, *
s->buf -
s->buf_start);
146 }
147
149 return 0;
150 }
151
154 {
159 }
160
161 /**
162 * Encode one strip in tiff file.
163 *
164 * @param s Tiff context
165 * @param src input buffer
166 * @param dst output buffer
167 * @param n size of input buffer
168 * @param compr compression method
169 * @return number of output bytes. If an output error is encountered, a negative
170 * value corresponding to an AVERROR error code is returned.
171 */
173 uint8_t *dst, int n, int compr)
174 {
175 switch (compr) {
176 #if CONFIG_ZLIB
179 {
180 unsigned long zlen =
s->buf_size - (*
s->buf -
s->buf_start);
181 if (compress(dst, &zlen,
src, n) != Z_OK) {
184 }
185 return zlen;
186 }
187 #endif
192 return n;
195 src, 1, n, 2, 0xff, -1, 0);
198 default:
200 compr);
202 }
203 }
204
206 uint8_t *dst, int lnum)
207 {
209 int w = (
s->width - 1) /
s->subsampling[0] + 1;
210 uint8_t *pu = &p->
data[1][lnum /
s->subsampling[1] * p->
linesize[1]];
212 if (
s->width %
s->subsampling[0] ||
s->height %
s->subsampling[1]) {
213 for (
i = 0;
i <
w;
i++) {
214 for (j = 0; j <
s->subsampling[1]; j++)
215 for (k = 0; k <
s->subsampling[0]; k++)
217 FFMIN(
i *
s->subsampling[0] + k,
s->width-1)];
218 *dst++ = *pu++;
220 }
221 }else{
222 for (
i = 0;
i <
w;
i++) {
223 for (j = 0; j <
s->subsampling[1]; j++)
224 for (k = 0; k <
s->subsampling[0]; k++)
226 i *
s->subsampling[0] + k];
227 *dst++ = *pu++;
229 }
230 }
231 }
232
233 #define ADD_ENTRY(s, tag, type, count, ptr_val) \
234 do { \
235 ret = add_entry(s, tag, type, count, ptr_val); \
236 if (ret < 0) \
237 goto fail; \
238 } while (0)
239
240 #define ADD_ENTRY1(s, tag, type, val) \
241 do { \
242 ret = add_entry1(s, tag, type, val); \
243 if (ret < 0) \
244 goto fail; \
245 } while (0)
246
248 const AVFrame *pict,
int *got_packet)
249 {
254 uint8_t *ptr;
256 uint32_t strips;
257 int bytes_per_row;
258 uint32_t res[2] = {
s->dpi, 1 };
// image resolution (72/1)
259 uint16_t bpp_tab[4];
261 int is_yuv = 0,
alpha = 0;
262 int shift_h, shift_v;
263 int packet_size;
264
267 s->subsampling[0] = 1;
268 s->subsampling[1] = 1;
269
272
275 s->bpp_tab_size =
desc->nb_components;
276
284 break;
293 break;
296 break;
299 break;
308 s->subsampling[0] = 1 << shift_h;
309 s->subsampling[1] = 1 << shift_v;
310 is_yuv = 1;
311 break;
312 default:
314 "This colors format is not supported\n");
316 }
317
318 for (
i = 0;
i <
s->bpp_tab_size;
i++)
319 bpp_tab[
i] =
desc->comp[
i].depth;
320
324 // best choice for DEFLATE
326 else
327 // suggest size of strip
328 s->rps =
FFMAX(8192 / (((
s->width *
s->bpp) >> 3) + 1), 1);
329 // round rps up
330 s->rps = ((
s->rps - 1) /
s->subsampling[1] + 1) *
s->subsampling[1];
331
332 strips = (
s->height - 1) /
s->rps + 1;
333
334 bytes_per_row = (((
s->width - 1) /
s->subsampling[0] + 1) *
s->bpp *
335 s->subsampling[0] *
s->subsampling[1] + 7) >> 3;
336 packet_size = avctx->
height * bytes_per_row * 2 +
338
345
349 }
350
351 // write header
352 bytestream_put_le16(&ptr, 0x4949);
353 bytestream_put_le16(&ptr, 42);
354
356 bytestream_put_le32(&ptr, 0);
357
358 if (strips > INT_MAX /
FFMAX(
sizeof(
s->strip_sizes[0]),
sizeof(
s->strip_offsets[0]))) {
361 }
364
365 if (!
s->strip_sizes || !
s->strip_offsets) {
368 }
369
370 if (is_yuv) {
372 if (
s->yuv_line ==
NULL) {
376 }
377 }
378
379 #if CONFIG_ZLIB
381 uint8_t *zbuf;
382 int zlen, zn;
383 int j;
384
385 zlen = bytes_per_row *
s->rps;
387 if (!zbuf) {
390 }
391 s->strip_offsets[0] = ptr -
pkt->
data;
392 zn = 0;
393 for (j = 0; j <
s->rps; j++) {
394 if (is_yuv) {
396 memcpy(zbuf + zn,
s->yuv_line, bytes_per_row);
397 j +=
s->subsampling[1] - 1;
398 } else
399 memcpy(zbuf + j * bytes_per_row,
401 zn += bytes_per_row;
402 }
408 }
410 s->strip_sizes[0] = ptr -
pkt->
data -
s->strip_offsets[0];
411 } else
412 #endif
413 {
419 }
420 }
421 for (
i = 0;
i <
s->height;
i++) {
422 if (
s->strip_sizes[
i /
s->rps] == 0) {
425 s->buf_size - (*
s->buf -
s->buf_start),
427 }
428 s->strip_offsets[
i /
s->rps] = ptr -
pkt->
data;
429 }
430 if (is_yuv) {
433 i +=
s->subsampling[1] - 1;
434 } else
436 ptr, bytes_per_row,
s->compr);
440 }
441 s->strip_sizes[
i /
s->rps] +=
ret;
444 (
i ==
s->height - 1 ||
i %
s->rps ==
s->rps - 1)) {
446 s->strip_sizes[(
i /
s->rps)] +=
ret;
448 }
449 }
452 }
453
455
459
462
466
469
479 }
482
486
488 uint16_t pal[256 * 3];
489 for (
i = 0;
i < 256;
i++) {
490 uint32_t
rgb = *(uint32_t *) (p->
data[1] +
i * 4);
491 pal[
i] = ((
rgb >> 16) & 0xff) * 257;
492 pal[
i + 256] = ((
rgb >> 8) & 0xff) * 257;
493 pal[
i + 512] = (
rgb & 0xff) * 257;
494 }
496 }
499 if (is_yuv) {
500 /** according to CCIR Recommendation 601.1 */
501 uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
506 }
507 // write offset to dir
509
513 }
514 bytestream_put_le16(&ptr,
s->num_entries);
// write tag count
516 bytestream_put_le32(&ptr, 0);
517
519 *got_packet = 1;
520
523 }
524
526 {
528
529 #if !CONFIG_ZLIB
532 "Deflate compression needs zlib compiled in\n");
534 }
535 #endif
536
538
539 return 0;
540 }
541
543 {
545
549
550 return 0;
551 }
552
553 #define OFFSET(x) offsetof(TiffEncoderContext, x)
554 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
563 };
564
570 };
571
590 },
593 };