tiffenc: use av_fast_padded_malloc(z)

Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Paul B Mahol 2012-07-10 03:01:19 +00:00
parent 0e003d8c91
commit 9b3f9f43a7

View File

@ -60,6 +60,12 @@ typedef struct TiffEncoderContext {
int bpp_tab_size; ///< bpp_tab size int bpp_tab_size; ///< bpp_tab size
int photometric_interpretation; ///< photometric interpretation int photometric_interpretation; ///< photometric interpretation
int strips; ///< number of strips int strips; ///< number of strips
uint32_t *strip_sizes;
unsigned int strip_sizes_size;
uint32_t *strip_offsets;
unsigned int strip_offsets_size;
uint8_t *yuv_line;
unsigned int yuv_line_size;
int rps; ///< row per strip int rps; ///< row per strip
uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
int num_entries; ///< number of entires int num_entries; ///< number of entires
@ -236,14 +242,11 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
uint8_t *ptr; uint8_t *ptr;
uint8_t *offset; uint8_t *offset;
uint32_t strips; uint32_t strips;
uint32_t *strip_sizes = NULL;
uint32_t *strip_offsets = NULL;
int bytes_per_row; int bytes_per_row;
uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1) uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1)
uint16_t bpp_tab[4]; uint16_t bpp_tab[4];
int ret = -1; int ret = -1;
int is_yuv = 0; int is_yuv = 0;
uint8_t *yuv_line = NULL;
int shift_h, shift_v; int shift_h, shift_v;
*p = *pict; *p = *pict;
@ -326,15 +329,20 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
offset = ptr; offset = ptr;
bytestream_put_le32(&ptr, 0); bytestream_put_le32(&ptr, 0);
strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips); av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips);
strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips); av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
if (!s->strip_sizes || !s->strip_offsets) {
ret = AVERROR(ENOMEM);
goto fail;
}
bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
* s->subsampling[0] * s->subsampling[1] + 7) >> 3; * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
if (is_yuv){ if (is_yuv){
yuv_line = av_malloc(bytes_per_row); av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
if (yuv_line == NULL){ if (s->yuv_line == NULL){
av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
} }
@ -347,12 +355,12 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
zlen = bytes_per_row * s->rps; zlen = bytes_per_row * s->rps;
zbuf = av_malloc(zlen); zbuf = av_malloc(zlen);
strip_offsets[0] = ptr - pkt->data; s->strip_offsets[0] = ptr - pkt->data;
zn = 0; zn = 0;
for (j = 0; j < s->rps; j++) { for (j = 0; j < s->rps; j++) {
if (is_yuv){ if (is_yuv){
pack_yuv(s, yuv_line, j); pack_yuv(s, s->yuv_line, j);
memcpy(zbuf + zn, yuv_line, bytes_per_row); memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
j += s->subsampling[1] - 1; j += s->subsampling[1] - 1;
} }
else else
@ -367,23 +375,23 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
goto fail; goto fail;
} }
ptr += ret; ptr += ret;
strip_sizes[0] = ptr - pkt->data - strip_offsets[0]; s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
} else } else
#endif #endif
{ {
if(s->compr == TIFF_LZW) if(s->compr == TIFF_LZW)
s->lzws = av_malloc(ff_lzw_encode_state_size); s->lzws = av_malloc(ff_lzw_encode_state_size);
for (i = 0; i < s->height; i++) { for (i = 0; i < s->height; i++) {
if (strip_sizes[i / s->rps] == 0) { if (s->strip_sizes[i / s->rps] == 0) {
if(s->compr == TIFF_LZW){ if(s->compr == TIFF_LZW){
ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start), ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
12, FF_LZW_TIFF, put_bits); 12, FF_LZW_TIFF, put_bits);
} }
strip_offsets[i / s->rps] = ptr - pkt->data; s->strip_offsets[i / s->rps] = ptr - pkt->data;
} }
if (is_yuv){ if (is_yuv){
pack_yuv(s, yuv_line, i); pack_yuv(s, s->yuv_line, i);
ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr); ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
i += s->subsampling[1] - 1; i += s->subsampling[1] - 1;
} }
else else
@ -393,11 +401,11 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
goto fail; goto fail;
} }
strip_sizes[i / s->rps] += ret; s->strip_sizes[i / s->rps] += ret;
ptr += ret; ptr += ret;
if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){ if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
ret = ff_lzw_encode_flush(s->lzws, flush_put_bits); ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
strip_sizes[(i / s->rps )] += ret ; s->strip_sizes[(i / s->rps )] += ret ;
ptr += ret; ptr += ret;
} }
} }
@ -416,13 +424,13 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr); add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr);
add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation); add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation);
add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, strip_offsets); add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, s->strip_offsets);
if (s->bpp_tab_size) if (s->bpp_tab_size)
add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size); add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps); add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps);
add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, strip_sizes); add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, s->strip_sizes);
add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res); add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res);
add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res); add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res);
add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2); add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2);
@ -462,12 +470,20 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
*got_packet = 1; *got_packet = 1;
fail: fail:
av_free(strip_sizes);
av_free(strip_offsets);
av_free(yuv_line);
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
static av_cold int encode_close(AVCodecContext *avctx)
{
TiffEncoderContext *s = avctx->priv_data;
av_freep(&s->strip_sizes);
av_freep(&s->strip_offsets);
av_freep(&s->yuv_line);
return 0;
}
#define OFFSET(x) offsetof(TiffEncoderContext, x) #define OFFSET(x) offsetof(TiffEncoderContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = { static const AVOption options[] = {
@ -496,6 +512,7 @@ AVCodec ff_tiff_encoder = {
.priv_data_size = sizeof(TiffEncoderContext), .priv_data_size = sizeof(TiffEncoderContext),
.init = encode_init, .init = encode_init,
.encode2 = encode_frame, .encode2 = encode_frame,
.close = encode_close,
.pix_fmts = (const enum PixelFormat[]) { .pix_fmts = (const enum PixelFormat[]) {
PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16LE, PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16LE,
PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE, PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,