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 const uint8_t *pu = &
p->data[1][lnum /
s->subsampling[1] *
p->linesize[1]];
211 const uint8_t *pv = &
p->data[2][lnum /
s->subsampling[1] *
p->linesize[2]];
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++)
216 *
dst++ =
p->data[0][
FFMIN(lnum + j,
s->height-1) *
p->linesize[0] +
217 FFMIN(
i *
s->subsampling[0] + k,
s->width-1)];
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++)
225 *
dst++ =
p->data[0][(lnum + j) *
p->linesize[0] +
226 i *
s->subsampling[0] + k];
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,
400 p->data[0] + j *
p->linesize[0], 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
468 if (sd) {
470 if (orientation >= 1 && orientation <= 8)
472 }
473
476
486 }
489
493
495 uint16_t pal[256 * 3];
496 for (
i = 0;
i < 256;
i++) {
497 uint32_t
rgb = *(uint32_t *) (
p->data[1] +
i * 4);
498 pal[
i] = ((
rgb >> 16) & 0xff) * 257;
499 pal[
i + 256] = ((
rgb >> 8) & 0xff) * 257;
500 pal[
i + 512] = (
rgb & 0xff) * 257;
501 }
503 }
506 if (is_yuv) {
507 /** according to CCIR Recommendation 601.1 */
508 uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
513 }
514 // write offset to dir
516
520 }
521 bytestream_put_le16(&ptr,
s->num_entries);
// write tag count
523 bytestream_put_le32(&ptr, 0);
524
526 *got_packet = 1;
527
530 }
531
533 {
535
536 #if !CONFIG_ZLIB
539 "Deflate compression needs zlib compiled in\n");
541 }
542 #endif
543
545
546 return 0;
547 }
548
550 {
552
556
557 return 0;
558 }
559
560 #define OFFSET(x) offsetof(TiffEncoderContext, x)
561 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
570 };
571
577 };
578
599 };