summaryrefslogtreecommitdiff
path: root/libavcodec/mjpegdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-09-06 00:57:50 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-09-06 01:19:37 +0200
commitc407c73457df8002142dfb043486a102e79b17b2 (patch)
tree78b651c4be75a6dcce8b9354b28b7885b54df7a9 /libavcodec/mjpegdec.c
parent1deeb9437c9c0e1f9cb708b24a4d0dedaee7bab3 (diff)
avcodec/mjpegdec: 12bit Grayscale support
Fixes part of Ticket2812 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/mjpegdec.c')
-rw-r--r--libavcodec/mjpegdec.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0d619efe49..856947b656 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -232,11 +232,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
if (s->bits == 9 && !s->pegasus_rct)
s->rct = 1; // FIXME ugly
- if (s->bits != 8 && !s->lossless) {
- av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");
- return -1;
- }
-
if(s->lossless && s->avctx->lowres){
av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n");
return -1;
@@ -270,6 +265,12 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
"bits/component or 16-bit gray");
return AVERROR_PATCHWELCOME;
}
+ if (!s->lossless && !(s->bits <= 8 || nb_components == 1)) {
+ avpriv_report_missing_feature(s->avctx,
+ "lossy that is not <= 8 "
+ "bits/component or 16-bit gray");
+ return AVERROR_PATCHWELCOME;
+ }
s->nb_components = nb_components;
s->h_max = 1;
s->v_max = 1;
@@ -1052,6 +1053,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
const uint8_t *reference_data[MAX_COMPONENTS];
int linesize[MAX_COMPONENTS];
GetBitContext mb_bitmask_gb;
+ int bytes_per_pixel = 1 + (s->bits > 8);
if (mb_bitmask)
init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
@@ -1101,7 +1103,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
y = 0;
for (j = 0; j < n; j++) {
block_offset = (((linesize[c] * (v * mb_y + y) * 8) +
- (h * mb_x + x) * 8) >> s->avctx->lowres);
+ (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);
if (s->interlaced && s->bottom_field)
block_offset += linesize[c] >> 1;
@@ -1123,9 +1125,15 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
s->dsp.idct_put(ptr, linesize[c], s->block);
if (s->bits & 7) {
int block_x, block_y;
+ if (s->bits > 8) {
+ for (block_y=0; block_y<8; block_y++)
+ for (block_x=0; block_x<8; block_x++)
+ *(uint16_t*)(ptr + 2*block_x + block_y*linesize[c]) <<= 16 - s->bits;
+ } else {
for (block_y=0; block_y<8; block_y++)
for (block_x=0; block_x<8; block_x++)
*(ptr + 2*block_x + block_y*linesize[c]) <<= 8 - s->bits;
+ }
}
}
} else {