interlaced files require horizontal-temporal transform that has been added. Output is not satisfactory yet! --- libavcodec/cfhd.c | 137 +++++++++++++++++++++++++++++++++++++++++------------- libavcodec/cfhd.h | 3 +- 2 files changed, 107 insertions(+), 33 deletions(-)
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index a064cd1599..da0f0fadf6 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -46,6 +46,7 @@ enum CFHDParam { SubbandNumber = 48, Quantization = 53, ChannelNumber = 62, + Progressive = 68, BitsPerComponent = 101, ChannelWidth = 104, ChannelHeight = 105, @@ -83,6 +84,7 @@ static void init_frame_defaults(CFHDContext *s) s->wavelet_depth = 3; s->pshift = 1; s->codebook = 0; + s->progressive = 0; init_plane_defaults(s); } @@ -137,6 +139,43 @@ static inline void filter(int16_t *output, ptrdiff_t out_stride, } } +static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int16_t *high, + int width, int linesize, int plane) +{ + int i; + int even, odd; + for (i = 0; i < width; i++) { + even = (*low - *high)/2; + odd = (*low + *high)/2; + + even = FFMIN(even, 1023); + even = FFMAX(even, 0); + odd = FFMIN(odd, 1023); + odd = FFMAX(odd, 0); + + output[i] = even; + output[i + linesize] = odd; + low++; + high++; + } +} + +static inline void horiz_haar_filter(int16_t *output, int16_t *low, int16_t *high, + int width) +{ + int i; + int even, odd; + for (i = 0; i < width; i+=2) { + even = (*low - *high); + odd = (*low + *high); + + output[i] = even; + output[i + 1] =odd; + low++; + high++; + } +} + static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, int width) { @@ -196,7 +235,8 @@ static int alloc_buffers(AVCodecContext *avctx) int width = i ? avctx->width >> chroma_x_shift : avctx->width; int height = i ? avctx->height >> chroma_y_shift : avctx->height; ptrdiff_t stride = FFALIGN(width / 8, 8) * 8; - if (chroma_y_shift) height = FFALIGN(height / 8, 2) * 8; + if (chroma_y_shift) + height = FFALIGN(height / 8, 2) * 8; s->plane[i].width = width; s->plane[i].height = height; s->plane[i].stride = stride; @@ -207,7 +247,6 @@ static int alloc_buffers(AVCodecContext *avctx) h4 = h8 * 2; w2 = w4 * 2; h2 = h4 * 2; - s->plane[i].idwt_buf = av_mallocz_array(height * stride, sizeof(*s->plane[i].idwt_buf)); s->plane[i].idwt_tmp = @@ -247,7 +286,6 @@ static int alloc_buffers(AVCodecContext *avctx) s->a_height = s->coded_height; s->a_width = s->coded_width; s->a_format = s->coded_format; - return 0; } @@ -277,6 +315,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, uint16_t data = bytestream2_get_be16(&gb); if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) { av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data); + } else if (tag == Progressive) { + av_log(avctx, AV_LOG_DEBUG, "Progressive? %"PRIu16"\n", 0x0001 & data); + s->progressive = 0x0001 & data; } else if (tag == ImageWidth) { av_log(avctx, AV_LOG_DEBUG, "Width %"PRIu16"\n", data); s->coded_width = data; @@ -757,7 +798,6 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, lowpass_height = s->plane[plane].band[2][1].height; lowpass_width = s->plane[plane].band[2][1].width; highpass_stride = s->plane[plane].band[2][1].stride; - if (lowpass_height > s->plane[plane].band[2][1].a_height || lowpass_width > s->plane[plane].band[2][1].a_width || !highpass_stride || s->plane[plane].band[2][1].width > s->plane[plane].band[2][1].a_width) { av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); @@ -766,36 +806,69 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } av_log(avctx, AV_LOG_DEBUG, "Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); + if (s->progressive) { + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[8]; + output = s->plane[plane].l_h[6]; + for (i = 0; i < lowpass_width; i++) { + vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height); + low++; + high++; + output++; + } + + low = s->plane[plane].subband[7]; + high = s->plane[plane].subband[9]; + output = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_width; i++) { + vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height); + low++; + high++; + output++; + } + + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_height * 2; i++) { + horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); + low += lowpass_width; + high += lowpass_width; + dst += pic->linesize[act_plane] / 2; + } + } else { + av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame); + pic->interlaced_frame = 1; + low = s->plane[plane].subband[0]; + high = s->plane[plane].subband[7]; + output = s->plane[plane].l_h[6]; + for (i = 0; i < lowpass_height; i++) { + horiz_filter(output, low, high, lowpass_width); + low += lowpass_width; + high += lowpass_width; + output += lowpass_width * 2; + } - low = s->plane[plane].subband[0]; - high = s->plane[plane].subband[8]; - output = s->plane[plane].l_h[6]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } - - low = s->plane[plane].subband[7]; - high = s->plane[plane].subband[9]; - output = s->plane[plane].l_h[7]; - for (i = 0; i < lowpass_width; i++) { - vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height); - low++; - high++; - output++; - } + low = s->plane[plane].subband[8]; + high = s->plane[plane].subband[9]; + output = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_height; i++) { + horiz_filter(output, low, high, lowpass_width); + low += lowpass_width; + high += lowpass_width; + output += lowpass_width * 2; + } - dst = (int16_t *)pic->data[act_plane]; - low = s->plane[plane].l_h[6]; - high = s->plane[plane].l_h[7]; - for (i = 0; i < lowpass_height * 2; i++) { - horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); - low += lowpass_width; - high += lowpass_width; - dst += pic->linesize[act_plane] / 2; - } + dst = (int16_t *)pic->data[act_plane]; + low = s->plane[plane].l_h[6]; + high = s->plane[plane].l_h[7]; + for (i = 0; i < lowpass_height; i++) { + interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); + low += lowpass_width * 2; + high += lowpass_width * 2; + dst += pic->linesize[act_plane]; + } + } } diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 2573e750a6..b17a88d07a 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -87,7 +87,8 @@ typedef struct CFHDContext { int a_width; int a_height; int a_format; - + int progressive; + int bpc; // bits per channel/component int channel_cnt; int subband_cnt; -- 2.14.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel