[Ffmpeg-devel] [PATCH] PNG 16-bit grayscale support

Kostya kostya.shishkov
Sun Oct 15 15:05:30 CEST 2006


On Sun, Oct 15, 2006 at 11:32:23AM +0200, Michael Niedermayer wrote:
> Hi
> 
> On Sun, Oct 15, 2006 at 08:24:42AM +0300, Kostya wrote:
> > On Sat, Oct 14, 2006 at 06:59:32PM +0200, Michael Niedermayer wrote:
> > > Hi
> > > 
> > > On Sat, Oct 14, 2006 at 03:43:22PM +0300, Kostya wrote:
> > > > This patch enables grayscale PNG decoding with 16-bit per sample size.
> > > > Sample is here:
> > > > http://samples.mplayerhq.hu/V-codecs/PNG/les_dns_xz.mov
> > > > (playable with MPlayer)
> > > 
> > > i would prefer if 16bit gray and rgb(a) formats would be exported without
> > > converting them to 8bit in the demuxer
> > 
> > And for now? Native 16bit depth is not supported.
> 
> add support :)
> i will not accpet colorspace conversation from usefull formats
> in the demuxer, ive never accepted that in the past either
> for totaly obfuscated formats which no display device or encoder would be
> able to use directly id make an exception but for normal 16bit rgb colorspace
> i will not
> 
> IMO its not so hard to move your 16->8bit loop into swscale, iam not asking
> that you rewrite swscale to actually be able to convert with 16bit precission
> 
> but converting in the demuxer means that no user application no matter if it
> supports 16bit rgb or not will be forced to live with 8bit precission

Okay, here is my variant using imgconvert, I'm not accustomed to swscale yet.
Mind that I don't value this as final patch, just RFC.

> [...]
> -- 
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> In the past you could go to a library and read, borrow or copy any book
> Today you'd get arrested for mere telling someone where the library is
> 
-------------- next part --------------
Index: libavutil/avutil.h
===================================================================
--- libavutil/avutil.h	(revision 6694)
+++ libavutil/avutil.h	(working copy)
@@ -35,7 +35,7 @@
 #define AV_TOSTRING(s) #s
 
 #define LIBAVUTIL_VERSION_INT   ((49<<16)+(0<<8)+1)
-#define LIBAVUTIL_VERSION       49.0.1
+#define LIBAVUTIL_VERSION       49.0.2
 #define LIBAVUTIL_BUILD         LIBAVUTIL_VERSION_INT
 
 #define LIBAVUTIL_IDENT         "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
@@ -105,6 +105,8 @@
     PIX_FMT_RGB32_1,   ///< Packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in cpu endianness
     PIX_FMT_BGR32_1,   ///< Packed RGB 8:8:8, 32bpp, (msb)8B 8G 8R 8A(lsb), in cpu endianness
 
+    PIX_FMT_GRAY16,     ///<        Y        , 16bpp big-endian
+
     PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
 };
 
Index: libavcodec/utils.c
===================================================================
--- libavcodec/utils.c	(revision 6694)
+++ libavcodec/utils.c	(working copy)
@@ -177,6 +177,7 @@
     case PIX_FMT_YUV422P:
     case PIX_FMT_YUV444P:
     case PIX_FMT_GRAY8:
+    case PIX_FMT_GRAY16:
     case PIX_FMT_YUVJ420P:
     case PIX_FMT_YUVJ422P:
     case PIX_FMT_YUVJ444P:
Index: libavcodec/imgconvert.c
===================================================================
--- libavcodec/imgconvert.c	(revision 6694)
+++ libavcodec/imgconvert.c	(working copy)
@@ -200,6 +200,13 @@
         .pixel_type = FF_PIXEL_PLANAR,
         .depth = 8,
     },
+    [PIX_FMT_GRAY16] = {
+        .name = "gray16",
+        .nb_channels = 1,
+        .color_type = FF_COLOR_GRAY,
+        .pixel_type = FF_PIXEL_PLANAR,
+        .depth = 16,
+    },
     [PIX_FMT_MONOWHITE] = {
         .name = "monow",
         .nb_channels = 1,
@@ -459,6 +466,12 @@
         picture->data[2] = NULL;
         picture->linesize[0] = width;
         return size;
+    case PIX_FMT_GRAY16:
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->linesize[0] = width * 2;
+        return size;
     case PIX_FMT_RGB4:
     case PIX_FMT_BGR4:
         picture->data[0] = ptr;
@@ -1842,6 +1855,30 @@
     gray_to_mono(dst, src, width, height, 0x00);
 }
 
+static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
+                           int width, int height)
+{
+    const uint8_t *s;
+    uint8_t *d;
+    int src_wrap, dst_wrap, x, y;
+
+    s = src->data[0];
+    src_wrap = src->linesize[0] - width * 2;
+
+    d = dst->data[0];
+    dst_wrap = dst->linesize[0] - width;
+
+    for(y=0;y<height;y++) {
+        for(x=0;x<width;x++) {
+            *d++ = *s++;
+            s++;
+        }
+        s += src_wrap;
+        d += dst_wrap;
+    }
+}
+
+
 typedef struct ConvertEntry {
     void (*convert)(AVPicture *dst,
                     const AVPicture *src, int width, int height);
@@ -2047,6 +2084,11 @@
             .convert = gray_to_monoblack
         },
     },
+    [PIX_FMT_GRAY16] = {
+        [PIX_FMT_GRAY8] = {
+            .convert = gray16_to_gray
+        },
+    },
     [PIX_FMT_MONOWHITE] = {
         [PIX_FMT_GRAY8] = {
             .convert = monowhite_to_gray
-------------- next part --------------
Index: libavcodec/png.c
===================================================================
--- libavcodec/png.c	(revision 6694)
+++ libavcodec/png.c	(working copy)
@@ -567,6 +567,9 @@
                 } else if (s->bit_depth == 8 &&
                            s->color_type == PNG_COLOR_TYPE_GRAY) {
                     avctx->pix_fmt = PIX_FMT_GRAY8;
+                } else if (s->bit_depth == 16 &&
+                           s->color_type == PNG_COLOR_TYPE_GRAY) {
+                    avctx->pix_fmt = PIX_FMT_GRAY16;
                 } else if (s->bit_depth == 1 &&
                            s->color_type == PNG_COLOR_TYPE_GRAY) {
                     avctx->pix_fmt = PIX_FMT_MONOBLACK;



More information about the ffmpeg-devel mailing list