diff mbox

[FFmpeg-devel] lavc/psd: Support 1bpp images

Message ID 201701101421.34179.cehoyos@ag.or.at
State Superseded
Headers show

Commit Message

Carl Eugen Hoyos Jan. 10, 2017, 1:21 p.m. UTC
Hi!

Attached patch fixes ticket #6044 for me.

Please comment, Carl Eugen
From 13fd23ed9dcb5e3affbb3456c64c3bb821b80613 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <cehoyos@ag.or.at>
Date: Tue, 10 Jan 2017 14:19:31 +0100
Subject: [PATCH] lavc/psd: Support 1bpp images.

Fixes ticket #6044.
---
 libavcodec/psd.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Gonzalo Garramuño Jan. 10, 2017, 6:45 p.m. UTC | #1
El 10/01/2017 a las 10:21, Carl Eugen Hoyos escribió:
>           }
> +    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
> +        ptr = picture->data[0];
> +        for (y = 0; y < s->height; y++) {
> +            memcpy(ptr, ptr_data, s->width + 7 >> 3);
> +            ptr_data += s->width + 7 >> 3;
> +            ptr += picture->linesize[0];
> +        }
Just a nitpick.  I would put s->width + 7 >> 3 in a variable outside the 
loop and use it in memcpy and in the ptr_data.
Carl Eugen Hoyos Jan. 10, 2017, 7 p.m. UTC | #2
2017-01-10 19:45 GMT+01:00 Gonzalo Garramuño <ggarra13@gmail.com>:
>
>
> El 10/01/2017 a las 10:21, Carl Eugen Hoyos escribió:
>>
>>           }
>> +    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
>> +        ptr = picture->data[0];
>> +        for (y = 0; y < s->height; y++) {
>> +            memcpy(ptr, ptr_data, s->width + 7 >> 3);
>> +            ptr_data += s->width + 7 >> 3;
>> +            ptr += picture->linesize[0];
>> +        }
>
> Just a nitpick.  I would put s->width + 7 >> 3 in a variable outside the
> loop and use it in memcpy and in the ptr_data.

Fixed locally.

Thank you, Carl Eugen
Martin Vignali Jan. 10, 2017, 10:42 p.m. UTC | #3
2017-01-10 20:00 GMT+01:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:

> 2017-01-10 19:45 GMT+01:00 Gonzalo Garramuño <ggarra13@gmail.com>:
> >
> >
> > El 10/01/2017 a las 10:21, Carl Eugen Hoyos escribió:
> >>
> >>           }
> >> +    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
> >> +        ptr = picture->data[0];
> >> +        for (y = 0; y < s->height; y++) {
> >> +            memcpy(ptr, ptr_data, s->width + 7 >> 3);
> >> +            ptr_data += s->width + 7 >> 3;
> >> +            ptr += picture->linesize[0];
> >> +        }
> >
> > Just a nitpick.  I would put s->width + 7 >> 3 in a variable outside the
> > loop and use it in memcpy and in the ptr_data.
>
> Fixed locally.
>
>
Tested on some sample, seems to work.

But maybe you can put the Store data code inside the planar part (it's very
similar)

Something like that
-------------------
     s->uncompressed_size = s->line_size * s->height * s->channel_count;

     switch (s->color_mode) {
+    case PSD_BITMAP:

Overwrite here the linesize :

s->line_size = s->width + 7 >> 3;

+        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+        break;
     case PSD_INDEXED:
         if (s->channel_depth != 8 || s->channel_count != 1) {
             av_log(s->avctx, AV_LOG_ERROR,
@@ -420,6 +423,13 @@ static int decode_frame(AVCodecContext *avctx, void
*data,
                 }
             }
         }




This special case can be delete :

+    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
+        ptr = picture->data[0];
+        for (y = 0; y < s->height; y++) {
+            memcpy(ptr, ptr_data, s->width + 7 >> 3);
+            ptr_data += s->width + 7 >> 3;
+            ptr += picture->linesize[0];
+        }

and the planar part, can use s->line_size instead of s->width *
s->pixel_size;

so will work for both i think

Martin
Carl Eugen Hoyos Jan. 10, 2017, 10:48 p.m. UTC | #4
2017-01-10 23:42 GMT+01:00 Martin Vignali <martin.vignali@gmail.com>:
> 2017-01-10 20:00 GMT+01:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>
>> 2017-01-10 19:45 GMT+01:00 Gonzalo Garramuño <ggarra13@gmail.com>:
>> >
>> >
>> > El 10/01/2017 a las 10:21, Carl Eugen Hoyos escribió:
>> >>
>> >>           }
>> >> +    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
>> >> +        ptr = picture->data[0];
>> >> +        for (y = 0; y < s->height; y++) {
>> >> +            memcpy(ptr, ptr_data, s->width + 7 >> 3);
>> >> +            ptr_data += s->width + 7 >> 3;
>> >> +            ptr += picture->linesize[0];
>> >> +        }
>> >
>> > Just a nitpick.  I would put s->width + 7 >> 3 in a variable outside the
>> > loop and use it in memcpy and in the ptr_data.
>>
>> Fixed locally.
>>
> Tested on some sample, seems to work.
>
> But maybe you can put the Store data code inside the planar part (it's very
> similar)

That means I have to remove the pixel_size context variable:
Do you want me to do that?

Carl Eugen
Martin Vignali Jan. 10, 2017, 10:53 p.m. UTC | #5
> > But maybe you can put the Store data code inside the planar part (it's
> very
> > similar)
>
> That means I have to remove the pixel_size context variable:
> Do you want me to do that?
>
> No i don't think you need to remove it.

You can override for this case, the s->linesize inside the switch case (see
my previous email)


And i forget in my previous email :
you need to add a check, if s->channel_count != 1 for bitmap.

Martin
Carl Eugen Hoyos Jan. 10, 2017, 10:56 p.m. UTC | #6
2017-01-10 23:53 GMT+01:00 Martin Vignali <martin.vignali@gmail.com>:
>> > But maybe you can put the Store data code inside the planar part
>> > (it's very similar)
>>
>> That means I have to remove the pixel_size context variable:
>> Do you want me to do that?
>
> No i don't think you need to remove it.

Then I don't know how to do it, please send a patch.
(Please mention the ticket.)

Thank you, Carl Eugen
diff mbox

Patch

diff --git a/libavcodec/psd.c b/libavcodec/psd.c
index 7587ed9..82a2c6b 100644
--- a/libavcodec/psd.c
+++ b/libavcodec/psd.c
@@ -319,6 +319,9 @@  static int decode_frame(AVCodecContext *avctx, void *data,
     s->uncompressed_size = s->line_size * s->height * s->channel_count;
 
     switch (s->color_mode) {
+    case PSD_BITMAP:
+        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+        break;
     case PSD_INDEXED:
         if (s->channel_depth != 8 || s->channel_count != 1) {
             av_log(s->avctx, AV_LOG_ERROR,
@@ -420,6 +423,13 @@  static int decode_frame(AVCodecContext *avctx, void *data,
                 }
             }
         }
+    } else if (avctx->pix_fmt == AV_PIX_FMT_MONOWHITE) {
+        ptr = picture->data[0];
+        for (y = 0; y < s->height; y++) {
+            memcpy(ptr, ptr_data, s->width + 7 >> 3);
+            ptr_data += s->width + 7 >> 3;
+            ptr += picture->linesize[0];
+        }
     } else {/* Planar */
         if (s->channel_count == 1)/* gray 8 or gray 16be */
             eq_channel[0] = 0;/* assign first channel, to first plane */