Commit 8cab24df authored by Benoit Fouet's avatar Benoit Fouet Committed by Michael Niedermayer

avcodec/pngdec: create a function to handle small (<=4) bits per pixel values.

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 24ca2ffa
......@@ -713,6 +713,79 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
return 0;
}
static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
{
if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) {
int i, j, k;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width / 8;
for (k = 7; k >= 1; k--)
if ((s->width&7) >= k)
pd[8*i + k - 1] = (pd[i]>>8-k) & 1;
for (i--; i >= 0; i--) {
pd[8*i + 7]= pd[i] & 1;
pd[8*i + 6]= (pd[i]>>1) & 1;
pd[8*i + 5]= (pd[i]>>2) & 1;
pd[8*i + 4]= (pd[i]>>3) & 1;
pd[8*i + 3]= (pd[i]>>4) & 1;
pd[8*i + 2]= (pd[i]>>5) & 1;
pd[8*i + 1]= (pd[i]>>6) & 1;
pd[8*i + 0]= pd[i]>>7;
}
pd += s->image_linesize;
}
} else if (s->bits_per_pixel == 2) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width / 4;
if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
if ((s->width&3) >= 1) pd[4*i + 0]= pd[i] >> 6;
for (i--; i >= 0; i--) {
pd[4*i + 3]= pd[i] & 3;
pd[4*i + 2]= (pd[i]>>2) & 3;
pd[4*i + 1]= (pd[i]>>4) & 3;
pd[4*i + 0]= pd[i]>>6;
}
} else {
if ((s->width&3) >= 3) pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
if ((s->width&3) >= 2) pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
if ((s->width&3) >= 1) pd[4*i + 0]= ( pd[i]>>6 )*0x55;
for (i--; i >= 0; i--) {
pd[4*i + 3]= ( pd[i] & 3)*0x55;
pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
pd[4*i + 0]= ( pd[i]>>6 )*0x55;
}
}
pd += s->image_linesize;
}
} else if (s->bits_per_pixel == 4) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width/2;
if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if (s->width&1) pd[2*i+0]= pd[i]>>4;
for (i--; i >= 0; i--) {
pd[2*i + 1] = pd[i] & 15;
pd[2*i + 0] = pd[i] >> 4;
}
} else {
if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
for (i--; i >= 0; i--) {
pd[2*i + 1] = (pd[i] & 15) * 0x11;
pd[2*i + 0] = (pd[i] >> 4) * 0x11;
}
}
pd += s->image_linesize;
}
}
}
static int decode_frame_png(AVCodecContext *avctx,
void *data, int *got_frame,
AVPacket *avpkt)
......@@ -820,75 +893,8 @@ skip_tag:
}
exit_loop:
if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) {
int i, j, k;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width / 8;
for (k = 7; k >= 1; k--)
if ((s->width&7) >= k)
pd[8*i + k - 1] = (pd[i]>>8-k) & 1;
for (i--; i >= 0; i--) {
pd[8*i + 7]= pd[i] & 1;
pd[8*i + 6]= (pd[i]>>1) & 1;
pd[8*i + 5]= (pd[i]>>2) & 1;
pd[8*i + 4]= (pd[i]>>3) & 1;
pd[8*i + 3]= (pd[i]>>4) & 1;
pd[8*i + 2]= (pd[i]>>5) & 1;
pd[8*i + 1]= (pd[i]>>6) & 1;
pd[8*i + 0]= pd[i]>>7;
}
pd += s->image_linesize;
}
} else if (s->bits_per_pixel == 2) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width / 4;
if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
if ((s->width&3) >= 1) pd[4*i + 0]= pd[i] >> 6;
for (i--; i >= 0; i--) {
pd[4*i + 3]= pd[i] & 3;
pd[4*i + 2]= (pd[i]>>2) & 3;
pd[4*i + 1]= (pd[i]>>4) & 3;
pd[4*i + 0]= pd[i]>>6;
}
} else {
if ((s->width&3) >= 3) pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
if ((s->width&3) >= 2) pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
if ((s->width&3) >= 1) pd[4*i + 0]= ( pd[i]>>6 )*0x55;
for (i--; i >= 0; i--) {
pd[4*i + 3]= ( pd[i] & 3)*0x55;
pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
pd[4*i + 0]= ( pd[i]>>6 )*0x55;
}
}
pd += s->image_linesize;
}
} else if (s->bits_per_pixel == 4) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width/2;
if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if (s->width&1) pd[2*i+0]= pd[i]>>4;
for (i--; i >= 0; i--) {
pd[2*i + 1] = pd[i] & 15;
pd[2*i + 0] = pd[i] >> 4;
}
} else {
if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
for (i--; i >= 0; i--) {
pd[2*i + 1] = (pd[i] & 15) * 0x11;
pd[2*i + 0] = (pd[i] >> 4) * 0x11;
}
}
pd += s->image_linesize;
}
}
if (s->bits_per_pixel <= 4)
handle_small_bpp(s, p);
/* handle p-frames only if a predecessor frame is available */
if (s->last_picture.f->data[0]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment