libavcodec/tiffenc.c
Go to the documentation of this file.
00001 /*
00002  * TIFF image encoder
00003  * Copyright (c) 2007 Bartlomiej Wolowiec
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00028 #include "libavutil/log.h"
00029 #include "libavutil/opt.h"
00030 
00031 #include "avcodec.h"
00032 #if CONFIG_ZLIB
00033 #include <zlib.h>
00034 #endif
00035 #include "libavutil/opt.h"
00036 #include "bytestream.h"
00037 #include "tiff.h"
00038 #include "rle.h"
00039 #include "lzw.h"
00040 #include "put_bits.h"
00041 
00042 #define TIFF_MAX_ENTRY 32
00043 
00045 static const uint8_t type_sizes2[6] = {
00046     0, 1, 1, 2, 4, 8
00047 };
00048 
00049 typedef struct TiffEncoderContext {
00050     AVClass *class;                     
00051     AVCodecContext *avctx;
00052     AVFrame picture;
00053 
00054     int width;                          
00055     int height;                         
00056     unsigned int bpp;                   
00057     int compr;                          
00058     int bpp_tab_size;                   
00059     int photometric_interpretation;     
00060     int strips;                         
00061     int rps;                            
00062     uint8_t entries[TIFF_MAX_ENTRY*12]; 
00063     int num_entries;                    
00064     uint8_t **buf;                      
00065     uint8_t *buf_start;                 
00066     int buf_size;                       
00067     uint16_t subsampling[2];            
00068     struct LZWEncodeState *lzws;        
00069     uint32_t dpi;                       
00070 } TiffEncoderContext;
00071 
00072 
00079 inline static int check_size(TiffEncoderContext * s, uint64_t need)
00080 {
00081     if (s->buf_size < *s->buf - s->buf_start + need) {
00082         *s->buf = s->buf_start + s->buf_size + 1;
00083         av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n");
00084         return 1;
00085     }
00086     return 0;
00087 }
00088 
00098 static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
00099                   int flip)
00100 {
00101     int i;
00102 #if HAVE_BIGENDIAN
00103     flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
00104 #endif
00105     for (i = 0; i < n * type_sizes2[type]; i++)
00106         *(*p)++ = val[i ^ flip];
00107 }
00108 
00117 static void add_entry(TiffEncoderContext * s,
00118                       enum TiffTags tag, enum TiffTypes type, int count,
00119                       const void *ptr_val)
00120 {
00121     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
00122 
00123     assert(s->num_entries < TIFF_MAX_ENTRY);
00124 
00125     bytestream_put_le16(&entries_ptr, tag);
00126     bytestream_put_le16(&entries_ptr, type);
00127     bytestream_put_le32(&entries_ptr, count);
00128 
00129     if (type_sizes[type] * count <= 4) {
00130         tnput(&entries_ptr, count, ptr_val, type, 0);
00131     } else {
00132         bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start);
00133         check_size(s, count * type_sizes2[type]);
00134         tnput(s->buf, count, ptr_val, type, 0);
00135     }
00136 
00137     s->num_entries++;
00138 }
00139 
00140 static void add_entry1(TiffEncoderContext * s,
00141                        enum TiffTags tag, enum TiffTypes type, int val){
00142     uint16_t w = val;
00143     uint32_t dw= val;
00144     add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw);
00145 }
00146 
00157 static int encode_strip(TiffEncoderContext * s, const int8_t * src,
00158                         uint8_t * dst, int n, int compr)
00159 {
00160 
00161     switch (compr) {
00162 #if CONFIG_ZLIB
00163     case TIFF_DEFLATE:
00164     case TIFF_ADOBE_DEFLATE:
00165         {
00166             unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
00167             if (compress(dst, &zlen, src, n) != Z_OK) {
00168                 av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
00169                 return -1;
00170             }
00171             return zlen;
00172         }
00173 #endif
00174     case TIFF_RAW:
00175         if (check_size(s, n))
00176             return -1;
00177         memcpy(dst, src, n);
00178         return n;
00179     case TIFF_PACKBITS:
00180         return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
00181     case TIFF_LZW:
00182         return ff_lzw_encode(s->lzws, src, n);
00183     default:
00184         return -1;
00185     }
00186 }
00187 
00188 static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
00189 {
00190     AVFrame *p = &s->picture;
00191     int i, j, k;
00192     int w = (s->width - 1) / s->subsampling[0] + 1;
00193     uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
00194     uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
00195     for (i = 0; i < w; i++){
00196         for (j = 0; j < s->subsampling[1]; j++)
00197             for (k = 0; k < s->subsampling[0]; k++)
00198                 *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
00199                                     i * s->subsampling[0] + k];
00200         *dst++ = *pu++;
00201         *dst++ = *pv++;
00202     }
00203 }
00204 
00205 static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
00206                         int buf_size, void *data)
00207 {
00208     TiffEncoderContext *s = avctx->priv_data;
00209     AVFrame *pict = data;
00210     AVFrame *const p = (AVFrame *) & s->picture;
00211     int i;
00212     int n;
00213     uint8_t *ptr = buf;
00214     uint8_t *offset;
00215     uint32_t strips;
00216     uint32_t *strip_sizes = NULL;
00217     uint32_t *strip_offsets = NULL;
00218     int bytes_per_row;
00219     uint32_t res[2] = { s->dpi, 1 };        // image resolution (72/1)
00220     uint16_t bpp_tab[] = { 8, 8, 8, 8 };
00221     int ret = -1;
00222     int is_yuv = 0;
00223     uint8_t *yuv_line = NULL;
00224     int shift_h, shift_v;
00225 
00226     s->avctx = avctx;
00227     s->buf_start = buf;
00228     s->buf = &ptr;
00229     s->buf_size = buf_size;
00230 
00231     *p = *pict;
00232     p->pict_type = AV_PICTURE_TYPE_I;
00233     p->key_frame = 1;
00234     avctx->coded_frame= &s->picture;
00235 
00236 #if FF_API_TIFFENC_COMPLEVEL
00237     if (avctx->compression_level != FF_COMPRESSION_DEFAULT)
00238         av_log(avctx, AV_LOG_WARNING, "Using compression_level to set compression "
00239                "algorithm is deprecated. Please use the compression_algo private "
00240                "option instead.\n");
00241     if (avctx->compression_level == 0) {
00242         s->compr = TIFF_RAW;
00243     } else if(avctx->compression_level == 2) {
00244         s->compr = TIFF_LZW;
00245 #if CONFIG_ZLIB
00246     } else if ((avctx->compression_level >= 3)) {
00247         s->compr = TIFF_DEFLATE;
00248 #endif
00249     }
00250 #endif
00251 
00252     s->width = avctx->width;
00253     s->height = avctx->height;
00254     s->subsampling[0] = 1;
00255     s->subsampling[1] = 1;
00256 
00257     switch (avctx->pix_fmt) {
00258     case PIX_FMT_RGBA64LE:
00259         s->bpp = 64;
00260         s->photometric_interpretation = 2;
00261         bpp_tab[0] = 16;
00262         bpp_tab[1] = 16;
00263         bpp_tab[2] = 16;
00264         bpp_tab[3] = 16;
00265         break;
00266     case PIX_FMT_RGB48LE:
00267         s->bpp = 48;
00268         s->photometric_interpretation = 2;
00269         bpp_tab[0] = 16;
00270         bpp_tab[1] = 16;
00271         bpp_tab[2] = 16;
00272         bpp_tab[3] = 16;
00273         break;
00274     case PIX_FMT_RGBA:
00275         s->bpp = 32;
00276         s->photometric_interpretation = 2;
00277         break;
00278     case PIX_FMT_RGB24:
00279         s->bpp = 24;
00280         s->photometric_interpretation = 2;
00281         break;
00282     case PIX_FMT_GRAY8:
00283         s->bpp = 8;
00284         s->photometric_interpretation = 1;
00285         break;
00286     case PIX_FMT_PAL8:
00287         s->bpp = 8;
00288         s->photometric_interpretation = 3;
00289         break;
00290     case PIX_FMT_MONOBLACK:
00291     case PIX_FMT_MONOWHITE:
00292         s->bpp = 1;
00293         s->photometric_interpretation = avctx->pix_fmt == PIX_FMT_MONOBLACK;
00294         bpp_tab[0] = 1;
00295         break;
00296     case PIX_FMT_YUV420P:
00297     case PIX_FMT_YUV422P:
00298     case PIX_FMT_YUV444P:
00299     case PIX_FMT_YUV410P:
00300     case PIX_FMT_YUV411P:
00301         s->photometric_interpretation = 6;
00302         avcodec_get_chroma_sub_sample(avctx->pix_fmt,
00303                 &shift_h, &shift_v);
00304         s->bpp = 8 + (16 >> (shift_h + shift_v));
00305         s->subsampling[0] = 1 << shift_h;
00306         s->subsampling[1] = 1 << shift_v;
00307         s->bpp_tab_size = 3;
00308         is_yuv = 1;
00309         break;
00310     default:
00311         av_log(s->avctx, AV_LOG_ERROR,
00312                "This colors format is not supported\n");
00313         return -1;
00314     }
00315     if (!is_yuv)
00316         s->bpp_tab_size = (s->bpp >= 48) ? ((s->bpp + 7) >> 4):((s->bpp + 7) >> 3);
00317 
00318     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
00319         //best choose for DEFLATE
00320         s->rps = s->height;
00321     else
00322         s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
00323     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
00324 
00325     strips = (s->height - 1) / s->rps + 1;
00326 
00327     if (check_size(s, 8))
00328         goto fail;
00329 
00330     // write header
00331     bytestream_put_le16(&ptr, 0x4949);
00332     bytestream_put_le16(&ptr, 42);
00333 
00334     offset = ptr;
00335     bytestream_put_le32(&ptr, 0);
00336 
00337     strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);
00338     strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
00339     if (!strip_sizes || !strip_offsets) {
00340         ret = AVERROR(ENOMEM);
00341         goto fail;
00342     }
00343 
00344     bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
00345                     * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
00346     if (is_yuv){
00347         yuv_line = av_malloc(bytes_per_row);
00348         if (yuv_line == NULL){
00349             av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
00350             ret = AVERROR(ENOMEM);
00351             goto fail;
00352         }
00353     }
00354 
00355 #if CONFIG_ZLIB
00356     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
00357         uint8_t *zbuf;
00358         int zlen, zn;
00359         int j;
00360 
00361         zlen = bytes_per_row * s->rps;
00362         zbuf = av_malloc(zlen);
00363         if (!zbuf) {
00364             ret = AVERROR(ENOMEM);
00365             goto fail;
00366         }
00367         strip_offsets[0] = ptr - buf;
00368         zn = 0;
00369         for (j = 0; j < s->rps; j++) {
00370             if (is_yuv){
00371                 pack_yuv(s, yuv_line, j);
00372                 memcpy(zbuf + zn, yuv_line, bytes_per_row);
00373                 j += s->subsampling[1] - 1;
00374             }
00375             else
00376                 memcpy(zbuf + j * bytes_per_row,
00377                        p->data[0] + j * p->linesize[0], bytes_per_row);
00378             zn += bytes_per_row;
00379         }
00380         n = encode_strip(s, zbuf, ptr, zn, s->compr);
00381         av_free(zbuf);
00382         if (n<0) {
00383             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
00384             goto fail;
00385         }
00386         ptr += n;
00387         strip_sizes[0] = ptr - buf - strip_offsets[0];
00388     } else
00389 #endif
00390     {
00391         if (s->compr == TIFF_LZW) {
00392             s->lzws = av_malloc(ff_lzw_encode_state_size);
00393             if (!s->lzws) {
00394                 ret = AVERROR(ENOMEM);
00395                 goto fail;
00396             }
00397         }
00398         for (i = 0; i < s->height; i++) {
00399             if (strip_sizes[i / s->rps] == 0) {
00400                 if(s->compr == TIFF_LZW){
00401                     ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
00402                                        12, FF_LZW_TIFF, put_bits);
00403                 }
00404                 strip_offsets[i / s->rps] = ptr - buf;
00405             }
00406             if (is_yuv){
00407                  pack_yuv(s, yuv_line, i);
00408                  n = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
00409                  i += s->subsampling[1] - 1;
00410             }
00411             else
00412                 n = encode_strip(s, p->data[0] + i * p->linesize[0],
00413                         ptr, bytes_per_row, s->compr);
00414             if (n < 0) {
00415                 av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
00416                 goto fail;
00417             }
00418             strip_sizes[i / s->rps] += n;
00419             ptr += n;
00420             if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
00421                 int ret;
00422                 ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
00423                 strip_sizes[(i / s->rps )] += ret ;
00424                 ptr += ret;
00425             }
00426         }
00427         if(s->compr == TIFF_LZW)
00428             av_free(s->lzws);
00429     }
00430 
00431     s->num_entries = 0;
00432 
00433     add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);
00434     add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);
00435     add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);
00436 
00437     if (s->bpp_tab_size)
00438     add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
00439 
00440     add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
00441     add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
00442     add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);
00443 
00444     if (s->bpp_tab_size)
00445     add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
00446 
00447     add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
00448     add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);
00449     add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
00450     add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
00451     add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
00452 
00453     if(!(avctx->flags & CODEC_FLAG_BITEXACT))
00454     add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
00455               strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
00456 
00457     if (avctx->pix_fmt == PIX_FMT_PAL8) {
00458         uint16_t pal[256 * 3];
00459         for (i = 0; i < 256; i++) {
00460             uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
00461             pal[i]       = ((rgb >> 16) & 0xff) * 257;
00462             pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
00463             pal[i + 512] = ( rgb        & 0xff) * 257;
00464         }
00465         add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
00466     }
00467     if (is_yuv){
00469         uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
00470         add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
00471         add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
00472     }
00473     bytestream_put_le32(&offset, ptr - buf);    // write offset to dir
00474 
00475     if (check_size(s, 6 + s->num_entries * 12))
00476         goto fail;
00477     bytestream_put_le16(&ptr, s->num_entries);  // write tag count
00478     bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);
00479     bytestream_put_le32(&ptr, 0);
00480 
00481     ret = ptr - buf;
00482 
00483 fail:
00484     av_free(strip_sizes);
00485     av_free(strip_offsets);
00486     av_free(yuv_line);
00487     return ret;
00488 }
00489 
00490 #define OFFSET(x) offsetof(TiffEncoderContext, x)
00491 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
00492 static const AVOption options[] = {
00493     {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.dbl = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
00494     { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
00495     { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
00496     { "raw",      NULL, 0, AV_OPT_TYPE_CONST, {TIFF_RAW},      0, 0, VE, "compression_algo" },
00497     { "lzw",      NULL, 0, AV_OPT_TYPE_CONST, {TIFF_LZW},      0, 0, VE, "compression_algo" },
00498 #if CONFIG_ZLIB
00499     { "deflate",  NULL, 0, AV_OPT_TYPE_CONST, {TIFF_DEFLATE},  0, 0, VE, "compression_algo" },
00500 #endif
00501     { NULL },
00502 };
00503 
00504 static const AVClass tiffenc_class = {
00505     .class_name = "TIFF encoder",
00506     .item_name  = av_default_item_name,
00507     .option     = options,
00508     .version    = LIBAVUTIL_VERSION_INT,
00509 };
00510 
00511 AVCodec ff_tiff_encoder = {
00512     .name           = "tiff",
00513     .type           = AVMEDIA_TYPE_VIDEO,
00514     .id             = CODEC_ID_TIFF,
00515     .priv_data_size = sizeof(TiffEncoderContext),
00516     .encode         = encode_frame,
00517     .pix_fmts =
00518         (const enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8,
00519                               PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,
00520                               PIX_FMT_YUV420P, PIX_FMT_YUV422P,
00521                               PIX_FMT_YUV444P, PIX_FMT_YUV410P,
00522                               PIX_FMT_YUV411P, PIX_FMT_RGB48LE,
00523                               PIX_FMT_RGBA, PIX_FMT_RGBA64LE, PIX_FMT_NONE},
00524     .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
00525     .priv_class     = &tiffenc_class,
00526 };