[FFmpeg-devel] [patch] support decoding png 1,2,4 bits

Julien Reichel Julien.Reichel
Thu Feb 14 10:41:50 CET 2008


HI,

Here is a patch for supporting decoding of png 1,2 and 4 bits.
Probably not the most efficient nor the most compact, but very simple
and non-intruisive.

Julien

Index: pngdec.c
===================================================================
--- pngdec.c	(revision 11931)
+++ pngdec.c	(working copy)
@@ -211,7 +211,46 @@
         src += 4;
     }
 }
+static void convert_to_8bit(uint8_t *dst, const uint8_t *src, int 
+width, int src_bits) {
+    int j;
+    unsigned int v;
 
+    if (src_bits==1){
+        for(j = 0;j < width; j+=8) {
+            v = src[0];
+            dst[0] = (v&0x80)>>7;
+            dst[1] = (v&0x40)>>6;
+            dst[2] = (v&0x20)>>5;
+            dst[3] = (v&0x10)>>4;
+            dst[4] = (v&0x08)>>3;
+            dst[5] = (v&0x04)>>2;
+            dst[6] = (v&0x02)>>1;
+            dst[7] = (v&0x01);
+            dst += 8;
+            src += 1;
+        }
+    }else if (src_bits==2){
+        for(j = 0;j < width; j+=4) {
+            v = src[0];
+            dst[0] = (v&0xC0)>>6;
+            dst[1] = (v&0x30)>>4;
+            dst[2] = (v&0x0C)>>2;
+            dst[3] = (v&0x03);
+            dst += 4;
+            src += 1;
+        }
+    }else{
+        for(j = 0;j < width; j+=2) {
+            v = src[0];
+            dst[0] = (v&0xF0)>>4;
+            dst[1] = (v&0x0F);
+            dst += 2;
+            src += 1;
+        }
+    }
+    
+}
 /* process exactly one decompressed row */  static void
png_handle_row(PNGDecContext *s)  { @@ -226,6 +265,11 @@
                            s->last_row, s->row_size, s->bpp);
             memcpy(s->last_row, s->tmp_row, s->row_size);
             convert_to_rgb32(ptr, s->tmp_row, s->width);
+        } else if (s->color_type == PNG_COLOR_TYPE_PALETTE &&
s->bit_depth<8) {
+            png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
+                           s->last_row, s->row_size, s->bpp);
+            memcpy(s->last_row, s->tmp_row, s->row_size);
+            convert_to_8bit(ptr, s->tmp_row, s->width, s->bit_depth);
         } else {
             /* in normal case, we avoid one copy */
             if (s->y == 0)
@@ -446,7 +490,8 @@
                 if (!s->last_row)
                     goto fail;
                 if (s->interlace_type ||
-                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+                    s->color_type == PNG_COLOR_TYPE_PALETTE && 
+ s->bit_depth<8 ) {
                     s->tmp_row = av_malloc(s->row_size);
                     if (!s->tmp_row)
                         goto fail;




More information about the ffmpeg-devel mailing list