diff mbox

[FFmpeg-devel] lavc/psd: Support CMYK images

Message ID CAB0OVGrsMifCaz8qcFpAh9HAkked3uHM8kPufCP_+yBwoZE6SA@mail.gmail.com
State Superseded
Headers show

Commit Message

Carl Eugen Hoyos Jan. 11, 2019, 1:55 a.m. UTC
Hi!

Attached patch fixes ticket #6797, please comment.

Carl Eugen
diff mbox

Patch

From f0d1c43a791f44eee5ae3174baf367a73e59283e Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Fri, 11 Jan 2019 02:53:06 +0100
Subject: [PATCH] lavc/psd: Support CMYK images.

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

diff --git a/libavcodec/psd.c b/libavcodec/psd.c
index 4381447..200e3ad 100644
--- a/libavcodec/psd.c
+++ b/libavcodec/psd.c
@@ -337,6 +337,19 @@  static int decode_frame(AVCodecContext *avctx, void *data,
         }
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
         break;
+    case PSD_CMYK:
+        if (s->channel_count == 5) {
+            if (s->channel_depth == 8) {
+                avctx->pix_fmt = AV_PIX_FMT_GBRAP;
+            } else {
+                avpriv_report_missing_feature(avctx, "channel depth %d for cmyk", s->channel_depth);
+                return AVERROR_PATCHWELCOME;
+            }
+        } else {
+            avpriv_report_missing_feature(avctx, "channel count %d for cmyk", s->channel_count);
+            return AVERROR_PATCHWELCOME;
+        }
+        break;
     case PSD_RGB:
         if (s->channel_count == 3) {
             if (s->channel_depth == 8) {
@@ -435,6 +448,36 @@  static int decode_frame(AVCodecContext *avctx, void *data,
                 }
             }
         }
+    } else if (s->color_mode == PSD_CMYK && avctx->pix_fmt == AV_PIX_FMT_GBRAP) {
+        uint8_t *dst[4] = { picture->data[0], picture->data[1], picture->data[2], picture->data[3] };
+        const uint8_t *src[5] = { ptr_data };
+        src[1] = src[0] + s->line_size * s->height;
+        src[2] = src[1] + s->line_size * s->height;
+        src[3] = src[2] + s->line_size * s->height;
+        src[4] = src[3] + s->line_size * s->height;
+        for (y = 0; y < s->height; y++) {
+            for (x = 0; x < s->width; x++) {
+                int k = src[3][x];
+                int r = src[0][x] * k;
+                int g = src[1][x] * k;
+                int b = src[2][x] * k;
+                dst[0][x] = g * 257 >> 16;
+                dst[1][x] = b * 257 >> 16;
+                dst[2][x] = r * 257 >> 16;
+            }
+            dst[0] += picture->linesize[0];
+            dst[1] += picture->linesize[1];
+            dst[2] += picture->linesize[2];
+            src[0] += s->line_size;
+            src[1] += s->line_size;
+            src[2] += s->line_size;
+            src[3] += s->line_size;
+        }
+        for (y = 0; y < s->height; y++) {
+            memcpy(dst[3], src[4], s->line_size);
+            src[4] += s->line_size;
+            dst[3] += picture->linesize[3];
+        }
     } else {/* Planar */
         if (s->channel_count == 1)/* gray 8 or gray 16be */
             eq_channel[0] = 0;/* assign first channel, to first plane */
-- 
1.7.10.4