annotate ffmpeg/libavcodec/tiffenc.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * TIFF image encoder
yading@10 3 * Copyright (c) 2007 Bartlomiej Wolowiec
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * TIFF image encoder
yading@10 25 * @author Bartlomiej Wolowiec
yading@10 26 */
yading@10 27
yading@10 28 #include "libavutil/imgutils.h"
yading@10 29 #include "libavutil/log.h"
yading@10 30 #include "libavutil/opt.h"
yading@10 31 #include "libavutil/pixdesc.h"
yading@10 32
yading@10 33 #include "avcodec.h"
yading@10 34 #include "config.h"
yading@10 35 #if CONFIG_ZLIB
yading@10 36 #include <zlib.h>
yading@10 37 #endif
yading@10 38 #include "bytestream.h"
yading@10 39 #include "internal.h"
yading@10 40 #include "tiff.h"
yading@10 41 #include "rle.h"
yading@10 42 #include "lzw.h"
yading@10 43 #include "put_bits.h"
yading@10 44
yading@10 45 #define TIFF_MAX_ENTRY 32
yading@10 46
yading@10 47 /** sizes of various TIFF field types (string size = 1)*/
yading@10 48 static const uint8_t type_sizes2[14] = {
yading@10 49 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
yading@10 50 };
yading@10 51
yading@10 52 typedef struct TiffEncoderContext {
yading@10 53 AVClass *class; ///< for private options
yading@10 54 AVCodecContext *avctx;
yading@10 55 AVFrame picture;
yading@10 56
yading@10 57 int width; ///< picture width
yading@10 58 int height; ///< picture height
yading@10 59 unsigned int bpp; ///< bits per pixel
yading@10 60 int compr; ///< compression level
yading@10 61 int bpp_tab_size; ///< bpp_tab size
yading@10 62 int photometric_interpretation; ///< photometric interpretation
yading@10 63 int strips; ///< number of strips
yading@10 64 uint32_t *strip_sizes;
yading@10 65 unsigned int strip_sizes_size;
yading@10 66 uint32_t *strip_offsets;
yading@10 67 unsigned int strip_offsets_size;
yading@10 68 uint8_t *yuv_line;
yading@10 69 unsigned int yuv_line_size;
yading@10 70 int rps; ///< row per strip
yading@10 71 uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
yading@10 72 int num_entries; ///< number of entires
yading@10 73 uint8_t **buf; ///< actual position in buffer
yading@10 74 uint8_t *buf_start; ///< pointer to first byte in buffer
yading@10 75 int buf_size; ///< buffer size
yading@10 76 uint16_t subsampling[2]; ///< YUV subsampling factors
yading@10 77 struct LZWEncodeState *lzws; ///< LZW Encode state
yading@10 78 uint32_t dpi; ///< image resolution in DPI
yading@10 79 } TiffEncoderContext;
yading@10 80
yading@10 81
yading@10 82 /**
yading@10 83 * Check free space in buffer.
yading@10 84 *
yading@10 85 * @param s Tiff context
yading@10 86 * @param need Needed bytes
yading@10 87 * @return 0 - ok, 1 - no free space
yading@10 88 */
yading@10 89 static inline int check_size(TiffEncoderContext * s, uint64_t need)
yading@10 90 {
yading@10 91 if (s->buf_size < *s->buf - s->buf_start + need) {
yading@10 92 *s->buf = s->buf_start + s->buf_size + 1;
yading@10 93 av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n");
yading@10 94 return 1;
yading@10 95 }
yading@10 96 return 0;
yading@10 97 }
yading@10 98
yading@10 99 /**
yading@10 100 * Put n values to buffer.
yading@10 101 *
yading@10 102 * @param p pointer to pointer to output buffer
yading@10 103 * @param n number of values
yading@10 104 * @param val pointer to values
yading@10 105 * @param type type of values
yading@10 106 * @param flip = 0 - normal copy, >0 - flip
yading@10 107 */
yading@10 108 static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
yading@10 109 int flip)
yading@10 110 {
yading@10 111 int i;
yading@10 112 #if HAVE_BIGENDIAN
yading@10 113 flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
yading@10 114 #endif
yading@10 115 for (i = 0; i < n * type_sizes2[type]; i++)
yading@10 116 *(*p)++ = val[i ^ flip];
yading@10 117 }
yading@10 118
yading@10 119 /**
yading@10 120 * Add entry to directory in tiff header.
yading@10 121 *
yading@10 122 * @param s Tiff context
yading@10 123 * @param tag tag that identifies the entry
yading@10 124 * @param type entry type
yading@10 125 * @param count the number of values
yading@10 126 * @param ptr_val pointer to values
yading@10 127 */
yading@10 128 static void add_entry(TiffEncoderContext * s,
yading@10 129 enum TiffTags tag, enum TiffTypes type, int count,
yading@10 130 const void *ptr_val)
yading@10 131 {
yading@10 132 uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
yading@10 133
yading@10 134 av_assert0(s->num_entries < TIFF_MAX_ENTRY);
yading@10 135
yading@10 136 bytestream_put_le16(&entries_ptr, tag);
yading@10 137 bytestream_put_le16(&entries_ptr, type);
yading@10 138 bytestream_put_le32(&entries_ptr, count);
yading@10 139
yading@10 140 if (type_sizes[type] * (int64_t)count <= 4) {
yading@10 141 tnput(&entries_ptr, count, ptr_val, type, 0);
yading@10 142 } else {
yading@10 143 bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
yading@10 144 check_size(s, count * (int64_t)type_sizes2[type]);
yading@10 145 tnput(s->buf, count, ptr_val, type, 0);
yading@10 146 }
yading@10 147
yading@10 148 s->num_entries++;
yading@10 149 }
yading@10 150
yading@10 151 static void add_entry1(TiffEncoderContext * s,
yading@10 152 enum TiffTags tag, enum TiffTypes type, int val){
yading@10 153 uint16_t w = val;
yading@10 154 uint32_t dw= val;
yading@10 155 add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw);
yading@10 156 }
yading@10 157
yading@10 158 /**
yading@10 159 * Encode one strip in tiff file.
yading@10 160 *
yading@10 161 * @param s Tiff context
yading@10 162 * @param src input buffer
yading@10 163 * @param dst output buffer
yading@10 164 * @param n size of input buffer
yading@10 165 * @param compr compression method
yading@10 166 * @return number of output bytes. If an output error is encountered, -1 is returned
yading@10 167 */
yading@10 168 static int encode_strip(TiffEncoderContext * s, const int8_t * src,
yading@10 169 uint8_t * dst, int n, int compr)
yading@10 170 {
yading@10 171
yading@10 172 switch (compr) {
yading@10 173 #if CONFIG_ZLIB
yading@10 174 case TIFF_DEFLATE:
yading@10 175 case TIFF_ADOBE_DEFLATE:
yading@10 176 {
yading@10 177 unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
yading@10 178 if (compress(dst, &zlen, src, n) != Z_OK) {
yading@10 179 av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
yading@10 180 return -1;
yading@10 181 }
yading@10 182 return zlen;
yading@10 183 }
yading@10 184 #endif
yading@10 185 case TIFF_RAW:
yading@10 186 if (check_size(s, n))
yading@10 187 return -1;
yading@10 188 memcpy(dst, src, n);
yading@10 189 return n;
yading@10 190 case TIFF_PACKBITS:
yading@10 191 return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
yading@10 192 case TIFF_LZW:
yading@10 193 return ff_lzw_encode(s->lzws, src, n);
yading@10 194 default:
yading@10 195 return -1;
yading@10 196 }
yading@10 197 }
yading@10 198
yading@10 199 static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
yading@10 200 {
yading@10 201 AVFrame *p = &s->picture;
yading@10 202 int i, j, k;
yading@10 203 int w = (s->width - 1) / s->subsampling[0] + 1;
yading@10 204 uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
yading@10 205 uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
yading@10 206 if(s->width % s->subsampling[0] || s->height % s->subsampling[1]){
yading@10 207 for (i = 0; i < w; i++){
yading@10 208 for (j = 0; j < s->subsampling[1]; j++)
yading@10 209 for (k = 0; k < s->subsampling[0]; k++)
yading@10 210 *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
yading@10 211 FFMIN(i * s->subsampling[0] + k, s->width-1)];
yading@10 212 *dst++ = *pu++;
yading@10 213 *dst++ = *pv++;
yading@10 214 }
yading@10 215 }else{
yading@10 216 for (i = 0; i < w; i++){
yading@10 217 for (j = 0; j < s->subsampling[1]; j++)
yading@10 218 for (k = 0; k < s->subsampling[0]; k++)
yading@10 219 *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
yading@10 220 i * s->subsampling[0] + k];
yading@10 221 *dst++ = *pu++;
yading@10 222 *dst++ = *pv++;
yading@10 223 }
yading@10 224 }
yading@10 225 }
yading@10 226
yading@10 227 static av_cold int encode_init(AVCodecContext *avctx)
yading@10 228 {
yading@10 229 TiffEncoderContext *s = avctx->priv_data;
yading@10 230
yading@10 231 avctx->coded_frame= &s->picture;
yading@10 232 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
yading@10 233 avctx->coded_frame->key_frame = 1;
yading@10 234 s->avctx = avctx;
yading@10 235
yading@10 236 return 0;
yading@10 237 }
yading@10 238
yading@10 239 static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
yading@10 240 const AVFrame *pict, int *got_packet)
yading@10 241 {
yading@10 242 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 243 TiffEncoderContext *s = avctx->priv_data;
yading@10 244 AVFrame *const p = &s->picture;
yading@10 245 int i;
yading@10 246 uint8_t *ptr;
yading@10 247 uint8_t *offset;
yading@10 248 uint32_t strips;
yading@10 249 int bytes_per_row;
yading@10 250 uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1)
yading@10 251 uint16_t bpp_tab[4];
yading@10 252 int ret = -1;
yading@10 253 int is_yuv = 0, alpha = 0;
yading@10 254 int shift_h, shift_v;
yading@10 255
yading@10 256 *p = *pict;
yading@10 257
yading@10 258 s->width = avctx->width;
yading@10 259 s->height = avctx->height;
yading@10 260 s->subsampling[0] = 1;
yading@10 261 s->subsampling[1] = 1;
yading@10 262
yading@10 263 avctx->bits_per_coded_sample =
yading@10 264 s->bpp = av_get_bits_per_pixel(desc);
yading@10 265 s->bpp_tab_size = desc->nb_components;
yading@10 266
yading@10 267 switch (avctx->pix_fmt) {
yading@10 268 case AV_PIX_FMT_RGBA64LE:
yading@10 269 case AV_PIX_FMT_RGBA:
yading@10 270 alpha = 1;
yading@10 271 case AV_PIX_FMT_RGB48LE:
yading@10 272 case AV_PIX_FMT_RGB24:
yading@10 273 s->photometric_interpretation = 2;
yading@10 274 break;
yading@10 275 case AV_PIX_FMT_GRAY8:
yading@10 276 avctx->bits_per_coded_sample = 0x28;
yading@10 277 case AV_PIX_FMT_GRAY8A:
yading@10 278 alpha = avctx->pix_fmt == AV_PIX_FMT_GRAY8A;
yading@10 279 case AV_PIX_FMT_GRAY16LE:
yading@10 280 case AV_PIX_FMT_MONOBLACK:
yading@10 281 s->photometric_interpretation = 1;
yading@10 282 break;
yading@10 283 case AV_PIX_FMT_PAL8:
yading@10 284 s->photometric_interpretation = 3;
yading@10 285 break;
yading@10 286 case AV_PIX_FMT_MONOWHITE:
yading@10 287 s->photometric_interpretation = 0;
yading@10 288 break;
yading@10 289 case AV_PIX_FMT_YUV420P:
yading@10 290 case AV_PIX_FMT_YUV422P:
yading@10 291 case AV_PIX_FMT_YUV440P:
yading@10 292 case AV_PIX_FMT_YUV444P:
yading@10 293 case AV_PIX_FMT_YUV410P:
yading@10 294 case AV_PIX_FMT_YUV411P:
yading@10 295 s->photometric_interpretation = 6;
yading@10 296 avcodec_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
yading@10 297 s->subsampling[0] = 1 << shift_h;
yading@10 298 s->subsampling[1] = 1 << shift_v;
yading@10 299 is_yuv = 1;
yading@10 300 break;
yading@10 301 default:
yading@10 302 av_log(s->avctx, AV_LOG_ERROR,
yading@10 303 "This colors format is not supported\n");
yading@10 304 return -1;
yading@10 305 }
yading@10 306
yading@10 307 for (i = 0; i < s->bpp_tab_size; i++)
yading@10 308 bpp_tab[i] = desc->comp[i].depth_minus1 + 1;
yading@10 309
yading@10 310 if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
yading@10 311 //best choose for DEFLATE
yading@10 312 s->rps = s->height;
yading@10 313 else
yading@10 314 s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1); // suggest size of strip
yading@10 315 s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
yading@10 316
yading@10 317 strips = (s->height - 1) / s->rps + 1;
yading@10 318
yading@10 319 if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * s->bpp * 2 +
yading@10 320 avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
yading@10 321 return ret;
yading@10 322 ptr = pkt->data;
yading@10 323 s->buf_start = pkt->data;
yading@10 324 s->buf = &ptr;
yading@10 325 s->buf_size = pkt->size;
yading@10 326
yading@10 327 if (check_size(s, 8))
yading@10 328 goto fail;
yading@10 329
yading@10 330 // write header
yading@10 331 bytestream_put_le16(&ptr, 0x4949);
yading@10 332 bytestream_put_le16(&ptr, 42);
yading@10 333
yading@10 334 offset = ptr;
yading@10 335 bytestream_put_le32(&ptr, 0);
yading@10 336
yading@10 337 av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips);
yading@10 338 av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
yading@10 339
yading@10 340 if (!s->strip_sizes || !s->strip_offsets) {
yading@10 341 ret = AVERROR(ENOMEM);
yading@10 342 goto fail;
yading@10 343 }
yading@10 344
yading@10 345 bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
yading@10 346 * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
yading@10 347 if (is_yuv){
yading@10 348 av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
yading@10 349 if (s->yuv_line == NULL){
yading@10 350 av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
yading@10 351 ret = AVERROR(ENOMEM);
yading@10 352 goto fail;
yading@10 353 }
yading@10 354 }
yading@10 355
yading@10 356 #if CONFIG_ZLIB
yading@10 357 if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
yading@10 358 uint8_t *zbuf;
yading@10 359 int zlen, zn;
yading@10 360 int j;
yading@10 361
yading@10 362 zlen = bytes_per_row * s->rps;
yading@10 363 zbuf = av_malloc(zlen);
yading@10 364 if (!zbuf) {
yading@10 365 ret = AVERROR(ENOMEM);
yading@10 366 goto fail;
yading@10 367 }
yading@10 368 s->strip_offsets[0] = ptr - pkt->data;
yading@10 369 zn = 0;
yading@10 370 for (j = 0; j < s->rps; j++) {
yading@10 371 if (is_yuv){
yading@10 372 pack_yuv(s, s->yuv_line, j);
yading@10 373 memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
yading@10 374 j += s->subsampling[1] - 1;
yading@10 375 }
yading@10 376 else
yading@10 377 memcpy(zbuf + j * bytes_per_row,
yading@10 378 p->data[0] + j * p->linesize[0], bytes_per_row);
yading@10 379 zn += bytes_per_row;
yading@10 380 }
yading@10 381 ret = encode_strip(s, zbuf, ptr, zn, s->compr);
yading@10 382 av_free(zbuf);
yading@10 383 if (ret < 0) {
yading@10 384 av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
yading@10 385 goto fail;
yading@10 386 }
yading@10 387 ptr += ret;
yading@10 388 s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
yading@10 389 } else
yading@10 390 #endif
yading@10 391 {
yading@10 392 if (s->compr == TIFF_LZW) {
yading@10 393 s->lzws = av_malloc(ff_lzw_encode_state_size);
yading@10 394 if (!s->lzws) {
yading@10 395 ret = AVERROR(ENOMEM);
yading@10 396 goto fail;
yading@10 397 }
yading@10 398 }
yading@10 399 for (i = 0; i < s->height; i++) {
yading@10 400 if (s->strip_sizes[i / s->rps] == 0) {
yading@10 401 if(s->compr == TIFF_LZW){
yading@10 402 ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
yading@10 403 12, FF_LZW_TIFF, put_bits);
yading@10 404 }
yading@10 405 s->strip_offsets[i / s->rps] = ptr - pkt->data;
yading@10 406 }
yading@10 407 if (is_yuv){
yading@10 408 pack_yuv(s, s->yuv_line, i);
yading@10 409 ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
yading@10 410 i += s->subsampling[1] - 1;
yading@10 411 }
yading@10 412 else
yading@10 413 ret = encode_strip(s, p->data[0] + i * p->linesize[0],
yading@10 414 ptr, bytes_per_row, s->compr);
yading@10 415 if (ret < 0) {
yading@10 416 av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
yading@10 417 goto fail;
yading@10 418 }
yading@10 419 s->strip_sizes[i / s->rps] += ret;
yading@10 420 ptr += ret;
yading@10 421 if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
yading@10 422 ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
yading@10 423 s->strip_sizes[(i / s->rps )] += ret ;
yading@10 424 ptr += ret;
yading@10 425 }
yading@10 426 }
yading@10 427 if(s->compr == TIFF_LZW)
yading@10 428 av_free(s->lzws);
yading@10 429 }
yading@10 430
yading@10 431 s->num_entries = 0;
yading@10 432
yading@10 433 add_entry1(s,TIFF_SUBFILE, TIFF_LONG, 0);
yading@10 434 add_entry1(s,TIFF_WIDTH, TIFF_LONG, s->width);
yading@10 435 add_entry1(s,TIFF_HEIGHT, TIFF_LONG, s->height);
yading@10 436
yading@10 437 if (s->bpp_tab_size)
yading@10 438 add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab);
yading@10 439
yading@10 440 add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr);
yading@10 441 add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation);
yading@10 442 add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, s->strip_offsets);
yading@10 443
yading@10 444 if (s->bpp_tab_size)
yading@10 445 add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
yading@10 446
yading@10 447 add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps);
yading@10 448 add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, s->strip_sizes);
yading@10 449 add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res);
yading@10 450 add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res);
yading@10 451 add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2);
yading@10 452
yading@10 453 if(!(avctx->flags & CODEC_FLAG_BITEXACT))
yading@10 454 add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING,
yading@10 455 strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
yading@10 456
yading@10 457 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
yading@10 458 uint16_t pal[256 * 3];
yading@10 459 for (i = 0; i < 256; i++) {
yading@10 460 uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
yading@10 461 pal[i] = ((rgb >> 16) & 0xff) * 257;
yading@10 462 pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
yading@10 463 pal[i + 512] = ( rgb & 0xff) * 257;
yading@10 464 }
yading@10 465 add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
yading@10 466 }
yading@10 467 if (alpha)
yading@10 468 add_entry1(s,TIFF_EXTRASAMPLES, TIFF_SHORT, 2);
yading@10 469 if (is_yuv){
yading@10 470 /** according to CCIR Recommendation 601.1 */
yading@10 471 uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
yading@10 472 add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT, 2, s->subsampling);
yading@10 473 if (avctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)
yading@10 474 add_entry1(s, TIFF_YCBCR_POSITIONING, TIFF_SHORT, 2);
yading@10 475 add_entry(s, TIFF_REFERENCE_BW, TIFF_RATIONAL, 6, refbw);
yading@10 476 }
yading@10 477 bytestream_put_le32(&offset, ptr - pkt->data); // write offset to dir
yading@10 478
yading@10 479 if (check_size(s, 6 + s->num_entries * 12)) {
yading@10 480 ret = AVERROR(EINVAL);
yading@10 481 goto fail;
yading@10 482 }
yading@10 483 bytestream_put_le16(&ptr, s->num_entries); // write tag count
yading@10 484 bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);
yading@10 485 bytestream_put_le32(&ptr, 0);
yading@10 486
yading@10 487 pkt->size = ptr - pkt->data;
yading@10 488 pkt->flags |= AV_PKT_FLAG_KEY;
yading@10 489 *got_packet = 1;
yading@10 490
yading@10 491 fail:
yading@10 492 return ret < 0 ? ret : 0;
yading@10 493 }
yading@10 494
yading@10 495 static av_cold int encode_close(AVCodecContext *avctx)
yading@10 496 {
yading@10 497 TiffEncoderContext *s = avctx->priv_data;
yading@10 498
yading@10 499 av_freep(&s->strip_sizes);
yading@10 500 av_freep(&s->strip_offsets);
yading@10 501 av_freep(&s->yuv_line);
yading@10 502
yading@10 503 return 0;
yading@10 504 }
yading@10 505
yading@10 506 #define OFFSET(x) offsetof(TiffEncoderContext, x)
yading@10 507 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
yading@10 508 static const AVOption options[] = {
yading@10 509 {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
yading@10 510 { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
yading@10 511 { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
yading@10 512 { "raw", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW}, 0, 0, VE, "compression_algo" },
yading@10 513 { "lzw", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_LZW}, 0, 0, VE, "compression_algo" },
yading@10 514 #if CONFIG_ZLIB
yading@10 515 { "deflate", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_DEFLATE}, 0, 0, VE, "compression_algo" },
yading@10 516 #endif
yading@10 517 { NULL },
yading@10 518 };
yading@10 519
yading@10 520 static const AVClass tiffenc_class = {
yading@10 521 .class_name = "TIFF encoder",
yading@10 522 .item_name = av_default_item_name,
yading@10 523 .option = options,
yading@10 524 .version = LIBAVUTIL_VERSION_INT,
yading@10 525 };
yading@10 526
yading@10 527 AVCodec ff_tiff_encoder = {
yading@10 528 .name = "tiff",
yading@10 529 .type = AVMEDIA_TYPE_VIDEO,
yading@10 530 .id = AV_CODEC_ID_TIFF,
yading@10 531 .priv_data_size = sizeof(TiffEncoderContext),
yading@10 532 .init = encode_init,
yading@10 533 .encode2 = encode_frame,
yading@10 534 .close = encode_close,
yading@10 535 .pix_fmts = (const enum AVPixelFormat[]) {
yading@10 536 AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
yading@10 537 AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE,
yading@10 538 AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_MONOWHITE,
yading@10 539 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
yading@10 540 AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_RGB48LE,
yading@10 541 AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
yading@10 542 AV_PIX_FMT_NONE
yading@10 543 },
yading@10 544 .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
yading@10 545 .priv_class = &tiffenc_class,
yading@10 546 };