1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Photoshop (PSD) image decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2016 Jokyo Images
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "bytestream.h"
23cabdff1aSopenharmony_ci#include "codec_internal.h"
24cabdff1aSopenharmony_ci#include "internal.h"
25cabdff1aSopenharmony_ci
26cabdff1aSopenharmony_cienum PsdCompr {
27cabdff1aSopenharmony_ci    PSD_RAW,
28cabdff1aSopenharmony_ci    PSD_RLE,
29cabdff1aSopenharmony_ci    PSD_ZIP_WITHOUT_P,
30cabdff1aSopenharmony_ci    PSD_ZIP_WITH_P,
31cabdff1aSopenharmony_ci};
32cabdff1aSopenharmony_ci
33cabdff1aSopenharmony_cienum PsdColorMode {
34cabdff1aSopenharmony_ci    PSD_BITMAP,
35cabdff1aSopenharmony_ci    PSD_GRAYSCALE,
36cabdff1aSopenharmony_ci    PSD_INDEXED,
37cabdff1aSopenharmony_ci    PSD_RGB,
38cabdff1aSopenharmony_ci    PSD_CMYK,
39cabdff1aSopenharmony_ci    PSD_MULTICHANNEL,
40cabdff1aSopenharmony_ci    PSD_DUOTONE,
41cabdff1aSopenharmony_ci    PSD_LAB,
42cabdff1aSopenharmony_ci};
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_citypedef struct PSDContext {
45cabdff1aSopenharmony_ci    AVClass *class;
46cabdff1aSopenharmony_ci    AVFrame *picture;
47cabdff1aSopenharmony_ci    AVCodecContext *avctx;
48cabdff1aSopenharmony_ci    GetByteContext gb;
49cabdff1aSopenharmony_ci
50cabdff1aSopenharmony_ci    uint8_t * tmp;
51cabdff1aSopenharmony_ci
52cabdff1aSopenharmony_ci    uint16_t channel_count;
53cabdff1aSopenharmony_ci    uint16_t channel_depth;
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ci    uint64_t uncompressed_size;
56cabdff1aSopenharmony_ci    unsigned int pixel_size;/* 1 for 8 bits, 2 for 16 bits */
57cabdff1aSopenharmony_ci    uint64_t line_size;/* length of src data (even width) */
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    int width;
60cabdff1aSopenharmony_ci    int height;
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci    enum PsdCompr compression;
63cabdff1aSopenharmony_ci    enum PsdColorMode color_mode;
64cabdff1aSopenharmony_ci
65cabdff1aSopenharmony_ci    uint8_t palette[AVPALETTE_SIZE];
66cabdff1aSopenharmony_ci} PSDContext;
67cabdff1aSopenharmony_ci
68cabdff1aSopenharmony_cistatic int decode_header(PSDContext * s)
69cabdff1aSopenharmony_ci{
70cabdff1aSopenharmony_ci    int signature, version, color_mode;
71cabdff1aSopenharmony_ci    int64_t len_section;
72cabdff1aSopenharmony_ci    int ret = 0;
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < 30) {/* File header section + color map data section length */
75cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");
76cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
77cabdff1aSopenharmony_ci    }
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci    signature = bytestream2_get_le32(&s->gb);
80cabdff1aSopenharmony_ci    if (signature != MKTAG('8','B','P','S')) {
81cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Wrong signature %d.\n", signature);
82cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
83cabdff1aSopenharmony_ci    }
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci    version = bytestream2_get_be16(&s->gb);
86cabdff1aSopenharmony_ci    if (version != 1) {
87cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Wrong version %d.\n", version);
88cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
89cabdff1aSopenharmony_ci    }
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci    bytestream2_skip(&s->gb, 6);/* reserved */
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_ci    s->channel_count = bytestream2_get_be16(&s->gb);
94cabdff1aSopenharmony_ci    if ((s->channel_count < 1) || (s->channel_count > 56)) {
95cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Invalid channel count %d.\n", s->channel_count);
96cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
97cabdff1aSopenharmony_ci    }
98cabdff1aSopenharmony_ci
99cabdff1aSopenharmony_ci    s->height = bytestream2_get_be32(&s->gb);
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci    if ((s->height > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
102cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR,
103cabdff1aSopenharmony_ci               "Height > 30000 is experimental, add "
104cabdff1aSopenharmony_ci               "'-strict %d' if you want to try to decode the picture.\n",
105cabdff1aSopenharmony_ci               FF_COMPLIANCE_EXPERIMENTAL);
106cabdff1aSopenharmony_ci        return AVERROR_EXPERIMENTAL;
107cabdff1aSopenharmony_ci    }
108cabdff1aSopenharmony_ci
109cabdff1aSopenharmony_ci    s->width = bytestream2_get_be32(&s->gb);
110cabdff1aSopenharmony_ci    if ((s->width > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
111cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR,
112cabdff1aSopenharmony_ci               "Width > 30000 is experimental, add "
113cabdff1aSopenharmony_ci               "'-strict %d' if you want to try to decode the picture.\n",
114cabdff1aSopenharmony_ci               FF_COMPLIANCE_EXPERIMENTAL);
115cabdff1aSopenharmony_ci        return AVERROR_EXPERIMENTAL;
116cabdff1aSopenharmony_ci    }
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_ci    if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
119cabdff1aSopenharmony_ci        return ret;
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    s->channel_depth = bytestream2_get_be16(&s->gb);
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci    color_mode = bytestream2_get_be16(&s->gb);
124cabdff1aSopenharmony_ci    switch (color_mode) {
125cabdff1aSopenharmony_ci    case 0:
126cabdff1aSopenharmony_ci        s->color_mode = PSD_BITMAP;
127cabdff1aSopenharmony_ci        break;
128cabdff1aSopenharmony_ci    case 1:
129cabdff1aSopenharmony_ci        s->color_mode = PSD_GRAYSCALE;
130cabdff1aSopenharmony_ci        break;
131cabdff1aSopenharmony_ci    case 2:
132cabdff1aSopenharmony_ci        s->color_mode = PSD_INDEXED;
133cabdff1aSopenharmony_ci        break;
134cabdff1aSopenharmony_ci    case 3:
135cabdff1aSopenharmony_ci        s->color_mode = PSD_RGB;
136cabdff1aSopenharmony_ci        break;
137cabdff1aSopenharmony_ci    case 4:
138cabdff1aSopenharmony_ci        s->color_mode = PSD_CMYK;
139cabdff1aSopenharmony_ci        break;
140cabdff1aSopenharmony_ci    case 7:
141cabdff1aSopenharmony_ci        s->color_mode = PSD_MULTICHANNEL;
142cabdff1aSopenharmony_ci        break;
143cabdff1aSopenharmony_ci    case 8:
144cabdff1aSopenharmony_ci        s->color_mode = PSD_DUOTONE;
145cabdff1aSopenharmony_ci        break;
146cabdff1aSopenharmony_ci    case 9:
147cabdff1aSopenharmony_ci        s->color_mode = PSD_LAB;
148cabdff1aSopenharmony_ci        break;
149cabdff1aSopenharmony_ci    default:
150cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Unknown color mode %d.\n", color_mode);
151cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
152cabdff1aSopenharmony_ci    }
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci    /* color map data */
155cabdff1aSopenharmony_ci    len_section = bytestream2_get_be32(&s->gb);
156cabdff1aSopenharmony_ci    if (len_section < 0) {
157cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Negative size for color map data section.\n");
158cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
159cabdff1aSopenharmony_ci    }
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
162cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
163cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
164cabdff1aSopenharmony_ci    }
165cabdff1aSopenharmony_ci    if (len_section) {
166cabdff1aSopenharmony_ci        int i,j;
167cabdff1aSopenharmony_ci        memset(s->palette, 0xff, AVPALETTE_SIZE);
168cabdff1aSopenharmony_ci        for (j = HAVE_BIGENDIAN; j < 3 + HAVE_BIGENDIAN; j++)
169cabdff1aSopenharmony_ci            for (i = 0; i < FFMIN(256, len_section / 3); i++)
170cabdff1aSopenharmony_ci                s->palette[i * 4 + (HAVE_BIGENDIAN ? j : 2 - j)] = bytestream2_get_byteu(&s->gb);
171cabdff1aSopenharmony_ci        len_section -= i * 3;
172cabdff1aSopenharmony_ci    }
173cabdff1aSopenharmony_ci    bytestream2_skip(&s->gb, len_section);
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci    /* image ressources */
176cabdff1aSopenharmony_ci    len_section = bytestream2_get_be32(&s->gb);
177cabdff1aSopenharmony_ci    if (len_section < 0) {
178cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Negative size for image ressources section.\n");
179cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
180cabdff1aSopenharmony_ci    }
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
183cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
184cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
185cabdff1aSopenharmony_ci    }
186cabdff1aSopenharmony_ci    bytestream2_skip(&s->gb, len_section);
187cabdff1aSopenharmony_ci
188cabdff1aSopenharmony_ci    /* layers and masks */
189cabdff1aSopenharmony_ci    len_section = bytestream2_get_be32(&s->gb);
190cabdff1aSopenharmony_ci    if (len_section < 0) {
191cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Negative size for layers and masks data section.\n");
192cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
193cabdff1aSopenharmony_ci    }
194cabdff1aSopenharmony_ci
195cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < len_section) {
196cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
197cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
198cabdff1aSopenharmony_ci    }
199cabdff1aSopenharmony_ci    bytestream2_skip(&s->gb, len_section);
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    /* image section */
202cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < 2) {
203cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "File without image data section.\n");
204cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
205cabdff1aSopenharmony_ci    }
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci    s->compression = bytestream2_get_be16(&s->gb);
208cabdff1aSopenharmony_ci    switch (s->compression) {
209cabdff1aSopenharmony_ci    case 0:
210cabdff1aSopenharmony_ci    case 1:
211cabdff1aSopenharmony_ci        break;
212cabdff1aSopenharmony_ci    case 2:
213cabdff1aSopenharmony_ci        avpriv_request_sample(s->avctx, "ZIP without predictor compression");
214cabdff1aSopenharmony_ci        return AVERROR_PATCHWELCOME;
215cabdff1aSopenharmony_ci    case 3:
216cabdff1aSopenharmony_ci        avpriv_request_sample(s->avctx, "ZIP with predictor compression");
217cabdff1aSopenharmony_ci        return AVERROR_PATCHWELCOME;
218cabdff1aSopenharmony_ci    default:
219cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Unknown compression %d.\n", s->compression);
220cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
221cabdff1aSopenharmony_ci    }
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci    return ret;
224cabdff1aSopenharmony_ci}
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_cistatic int decode_rle(PSDContext * s){
227cabdff1aSopenharmony_ci    unsigned int scanline_count;
228cabdff1aSopenharmony_ci    unsigned int sl, count;
229cabdff1aSopenharmony_ci    unsigned long target_index = 0;
230cabdff1aSopenharmony_ci    unsigned int p;
231cabdff1aSopenharmony_ci    int8_t rle_char;
232cabdff1aSopenharmony_ci    unsigned int repeat_count;
233cabdff1aSopenharmony_ci    uint8_t v;
234cabdff1aSopenharmony_ci
235cabdff1aSopenharmony_ci    scanline_count = s->height * s->channel_count;
236cabdff1aSopenharmony_ci
237cabdff1aSopenharmony_ci    /* scanline table */
238cabdff1aSopenharmony_ci    if (bytestream2_get_bytes_left(&s->gb) < scanline_count * 2) {
239cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline table.\n");
240cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
241cabdff1aSopenharmony_ci    }
242cabdff1aSopenharmony_ci    bytestream2_skip(&s->gb, scanline_count * 2);/* size of each scanline */
243cabdff1aSopenharmony_ci
244cabdff1aSopenharmony_ci    /* decode rle data scanline by scanline */
245cabdff1aSopenharmony_ci    for (sl = 0; sl < scanline_count; sl++) {
246cabdff1aSopenharmony_ci        count = 0;
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_ci        while (count < s->line_size) {
249cabdff1aSopenharmony_ci            rle_char = bytestream2_get_byte(&s->gb);
250cabdff1aSopenharmony_ci
251cabdff1aSopenharmony_ci            if (rle_char <= 0) {/* byte repeat */
252cabdff1aSopenharmony_ci                repeat_count = rle_char * -1;
253cabdff1aSopenharmony_ci
254cabdff1aSopenharmony_ci                if (bytestream2_get_bytes_left(&s->gb) < 1) {
255cabdff1aSopenharmony_ci                    av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
256cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
257cabdff1aSopenharmony_ci                }
258cabdff1aSopenharmony_ci
259cabdff1aSopenharmony_ci                if (target_index + repeat_count >= s->uncompressed_size) {
260cabdff1aSopenharmony_ci                    av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
261cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
262cabdff1aSopenharmony_ci                }
263cabdff1aSopenharmony_ci
264cabdff1aSopenharmony_ci                v = bytestream2_get_byte(&s->gb);
265cabdff1aSopenharmony_ci                for (p = 0; p <= repeat_count; p++) {
266cabdff1aSopenharmony_ci                    s->tmp[target_index++] = v;
267cabdff1aSopenharmony_ci                }
268cabdff1aSopenharmony_ci                count += repeat_count + 1;
269cabdff1aSopenharmony_ci            } else {
270cabdff1aSopenharmony_ci                if (bytestream2_get_bytes_left(&s->gb) < rle_char) {
271cabdff1aSopenharmony_ci                    av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
272cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
273cabdff1aSopenharmony_ci                }
274cabdff1aSopenharmony_ci
275cabdff1aSopenharmony_ci                if (target_index + rle_char >= s->uncompressed_size) {
276cabdff1aSopenharmony_ci                    av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
277cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
278cabdff1aSopenharmony_ci                }
279cabdff1aSopenharmony_ci
280cabdff1aSopenharmony_ci                for (p = 0; p <= rle_char; p++) {
281cabdff1aSopenharmony_ci                    v = bytestream2_get_byte(&s->gb);
282cabdff1aSopenharmony_ci                    s->tmp[target_index++] = v;
283cabdff1aSopenharmony_ci                }
284cabdff1aSopenharmony_ci                count += rle_char + 1;
285cabdff1aSopenharmony_ci            }
286cabdff1aSopenharmony_ci        }
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci
289cabdff1aSopenharmony_ci    return 0;
290cabdff1aSopenharmony_ci}
291cabdff1aSopenharmony_ci
292cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *picture,
293cabdff1aSopenharmony_ci                        int *got_frame, AVPacket *avpkt)
294cabdff1aSopenharmony_ci{
295cabdff1aSopenharmony_ci    int ret;
296cabdff1aSopenharmony_ci    uint8_t *ptr;
297cabdff1aSopenharmony_ci    const uint8_t *ptr_data;
298cabdff1aSopenharmony_ci    int index_out, c, y, x, p;
299cabdff1aSopenharmony_ci    uint8_t eq_channel[4] = {2,0,1,3};/* RGBA -> GBRA channel order */
300cabdff1aSopenharmony_ci    uint8_t plane_number;
301cabdff1aSopenharmony_ci
302cabdff1aSopenharmony_ci    PSDContext *s = avctx->priv_data;
303cabdff1aSopenharmony_ci    s->avctx     = avctx;
304cabdff1aSopenharmony_ci    s->channel_count = 0;
305cabdff1aSopenharmony_ci    s->channel_depth = 0;
306cabdff1aSopenharmony_ci    s->tmp           = NULL;
307cabdff1aSopenharmony_ci    s->line_size     = 0;
308cabdff1aSopenharmony_ci
309cabdff1aSopenharmony_ci    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
310cabdff1aSopenharmony_ci
311cabdff1aSopenharmony_ci    if ((ret = decode_header(s)) < 0)
312cabdff1aSopenharmony_ci        return ret;
313cabdff1aSopenharmony_ci
314cabdff1aSopenharmony_ci    s->pixel_size = s->channel_depth >> 3;/* in byte */
315cabdff1aSopenharmony_ci    s->line_size = s->width * s->pixel_size;
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci    switch (s->color_mode) {
318cabdff1aSopenharmony_ci    case PSD_BITMAP:
319cabdff1aSopenharmony_ci        if (s->channel_depth != 1 || s->channel_count != 1) {
320cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_ERROR,
321cabdff1aSopenharmony_ci                    "Invalid bitmap file (channel_depth %d, channel_count %d)\n",
322cabdff1aSopenharmony_ci                    s->channel_depth, s->channel_count);
323cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
324cabdff1aSopenharmony_ci        }
325cabdff1aSopenharmony_ci        s->line_size = s->width + 7 >> 3;
326cabdff1aSopenharmony_ci        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
327cabdff1aSopenharmony_ci        break;
328cabdff1aSopenharmony_ci    case PSD_INDEXED:
329cabdff1aSopenharmony_ci        if (s->channel_depth != 8 || s->channel_count != 1) {
330cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_ERROR,
331cabdff1aSopenharmony_ci                   "Invalid indexed file (channel_depth %d, channel_count %d)\n",
332cabdff1aSopenharmony_ci                   s->channel_depth, s->channel_count);
333cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
334cabdff1aSopenharmony_ci        }
335cabdff1aSopenharmony_ci        avctx->pix_fmt = AV_PIX_FMT_PAL8;
336cabdff1aSopenharmony_ci        break;
337cabdff1aSopenharmony_ci    case PSD_CMYK:
338cabdff1aSopenharmony_ci        if (s->channel_count == 4) {
339cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
340cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRP;
341cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
342cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRP16BE;
343cabdff1aSopenharmony_ci            } else {
344cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for cmyk", s->channel_depth);
345cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
346cabdff1aSopenharmony_ci            }
347cabdff1aSopenharmony_ci        } else if (s->channel_count == 5) {
348cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
349cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRAP;
350cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
351cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRAP16BE;
352cabdff1aSopenharmony_ci            } else {
353cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for cmyk", s->channel_depth);
354cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
355cabdff1aSopenharmony_ci            }
356cabdff1aSopenharmony_ci        } else {
357cabdff1aSopenharmony_ci            avpriv_report_missing_feature(avctx, "channel count %d for cmyk", s->channel_count);
358cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
359cabdff1aSopenharmony_ci        }
360cabdff1aSopenharmony_ci        break;
361cabdff1aSopenharmony_ci    case PSD_RGB:
362cabdff1aSopenharmony_ci        if (s->channel_count == 3) {
363cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
364cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRP;
365cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
366cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRP16BE;
367cabdff1aSopenharmony_ci            } else {
368cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
369cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
370cabdff1aSopenharmony_ci            }
371cabdff1aSopenharmony_ci        } else if (s->channel_count == 4) {
372cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
373cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRAP;
374cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
375cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GBRAP16BE;
376cabdff1aSopenharmony_ci            } else {
377cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
378cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
379cabdff1aSopenharmony_ci            }
380cabdff1aSopenharmony_ci        } else {
381cabdff1aSopenharmony_ci            avpriv_report_missing_feature(avctx, "channel count %d for rgb", s->channel_count);
382cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
383cabdff1aSopenharmony_ci        }
384cabdff1aSopenharmony_ci        break;
385cabdff1aSopenharmony_ci    case PSD_DUOTONE:
386cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_WARNING, "ignoring unknown duotone specification.\n");
387cabdff1aSopenharmony_ci    case PSD_GRAYSCALE:
388cabdff1aSopenharmony_ci        if (s->channel_count == 1) {
389cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
390cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GRAY8;
391cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
392cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
393cabdff1aSopenharmony_ci            } else if (s->channel_depth == 32) {
394cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_GRAYF32BE;
395cabdff1aSopenharmony_ci            } else {
396cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
397cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
398cabdff1aSopenharmony_ci            }
399cabdff1aSopenharmony_ci        } else if (s->channel_count == 2) {
400cabdff1aSopenharmony_ci            if (s->channel_depth == 8) {
401cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_YA8;
402cabdff1aSopenharmony_ci            } else if (s->channel_depth == 16) {
403cabdff1aSopenharmony_ci                avctx->pix_fmt = AV_PIX_FMT_YA16BE;
404cabdff1aSopenharmony_ci            } else {
405cabdff1aSopenharmony_ci                avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
406cabdff1aSopenharmony_ci                return AVERROR_PATCHWELCOME;
407cabdff1aSopenharmony_ci            }
408cabdff1aSopenharmony_ci        } else {
409cabdff1aSopenharmony_ci            avpriv_report_missing_feature(avctx, "channel count %d for grayscale", s->channel_count);
410cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
411cabdff1aSopenharmony_ci        }
412cabdff1aSopenharmony_ci        break;
413cabdff1aSopenharmony_ci    default:
414cabdff1aSopenharmony_ci        avpriv_report_missing_feature(avctx, "color mode %d", s->color_mode);
415cabdff1aSopenharmony_ci        return AVERROR_PATCHWELCOME;
416cabdff1aSopenharmony_ci    }
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_ci    s->uncompressed_size = s->line_size * s->height * s->channel_count;
419cabdff1aSopenharmony_ci
420cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
421cabdff1aSopenharmony_ci        return ret;
422cabdff1aSopenharmony_ci
423cabdff1aSopenharmony_ci    /* decode picture if need */
424cabdff1aSopenharmony_ci    if (s->compression == PSD_RLE) {
425cabdff1aSopenharmony_ci        s->tmp = av_malloc(s->uncompressed_size);
426cabdff1aSopenharmony_ci        if (!s->tmp)
427cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
428cabdff1aSopenharmony_ci
429cabdff1aSopenharmony_ci        ret = decode_rle(s);
430cabdff1aSopenharmony_ci
431cabdff1aSopenharmony_ci        if (ret < 0) {
432cabdff1aSopenharmony_ci            av_freep(&s->tmp);
433cabdff1aSopenharmony_ci            return ret;
434cabdff1aSopenharmony_ci        }
435cabdff1aSopenharmony_ci
436cabdff1aSopenharmony_ci        ptr_data = s->tmp;
437cabdff1aSopenharmony_ci    } else {
438cabdff1aSopenharmony_ci        if (bytestream2_get_bytes_left(&s->gb) < s->uncompressed_size) {
439cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_ERROR, "Not enough data for raw image data section.\n");
440cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
441cabdff1aSopenharmony_ci        }
442cabdff1aSopenharmony_ci        ptr_data = s->gb.buffer;
443cabdff1aSopenharmony_ci    }
444cabdff1aSopenharmony_ci
445cabdff1aSopenharmony_ci    /* Store data */
446cabdff1aSopenharmony_ci    if ((avctx->pix_fmt == AV_PIX_FMT_YA8)||(avctx->pix_fmt == AV_PIX_FMT_YA16BE)){/* Interleaved */
447cabdff1aSopenharmony_ci        ptr = picture->data[0];
448cabdff1aSopenharmony_ci        for (c = 0; c < s->channel_count; c++) {
449cabdff1aSopenharmony_ci            for (y = 0; y < s->height; y++) {
450cabdff1aSopenharmony_ci                for (x = 0; x < s->width; x++) {
451cabdff1aSopenharmony_ci                    index_out = y * picture->linesize[0] + x * s->channel_count * s->pixel_size + c * s->pixel_size;
452cabdff1aSopenharmony_ci                    for (p = 0; p < s->pixel_size; p++) {
453cabdff1aSopenharmony_ci                        ptr[index_out + p] = *ptr_data;
454cabdff1aSopenharmony_ci                        ptr_data ++;
455cabdff1aSopenharmony_ci                    }
456cabdff1aSopenharmony_ci                }
457cabdff1aSopenharmony_ci            }
458cabdff1aSopenharmony_ci        }
459cabdff1aSopenharmony_ci    } else if (s->color_mode == PSD_CMYK) {
460cabdff1aSopenharmony_ci        uint8_t *dst[4] = { picture->data[0], picture->data[1], picture->data[2], picture->data[3] };
461cabdff1aSopenharmony_ci        const uint8_t *src[5] = { ptr_data };
462cabdff1aSopenharmony_ci        src[1] = src[0] + s->line_size * s->height;
463cabdff1aSopenharmony_ci        src[2] = src[1] + s->line_size * s->height;
464cabdff1aSopenharmony_ci        src[3] = src[2] + s->line_size * s->height;
465cabdff1aSopenharmony_ci        src[4] = src[3] + s->line_size * s->height;
466cabdff1aSopenharmony_ci        if (s->channel_depth == 8) {
467cabdff1aSopenharmony_ci            for (y = 0; y < s->height; y++) {
468cabdff1aSopenharmony_ci                for (x = 0; x < s->width; x++) {
469cabdff1aSopenharmony_ci                    int k = src[3][x];
470cabdff1aSopenharmony_ci                    int r = src[0][x] * k;
471cabdff1aSopenharmony_ci                    int g = src[1][x] * k;
472cabdff1aSopenharmony_ci                    int b = src[2][x] * k;
473cabdff1aSopenharmony_ci                    dst[0][x] = g * 257 >> 16;
474cabdff1aSopenharmony_ci                    dst[1][x] = b * 257 >> 16;
475cabdff1aSopenharmony_ci                    dst[2][x] = r * 257 >> 16;
476cabdff1aSopenharmony_ci                }
477cabdff1aSopenharmony_ci                dst[0] += picture->linesize[0];
478cabdff1aSopenharmony_ci                dst[1] += picture->linesize[1];
479cabdff1aSopenharmony_ci                dst[2] += picture->linesize[2];
480cabdff1aSopenharmony_ci                src[0] += s->line_size;
481cabdff1aSopenharmony_ci                src[1] += s->line_size;
482cabdff1aSopenharmony_ci                src[2] += s->line_size;
483cabdff1aSopenharmony_ci                src[3] += s->line_size;
484cabdff1aSopenharmony_ci            }
485cabdff1aSopenharmony_ci            if (avctx->pix_fmt == AV_PIX_FMT_GBRAP) {
486cabdff1aSopenharmony_ci                for (y = 0; y < s->height; y++) {
487cabdff1aSopenharmony_ci                    memcpy(dst[3], src[4], s->line_size);
488cabdff1aSopenharmony_ci                    src[4] += s->line_size;
489cabdff1aSopenharmony_ci                    dst[3] += picture->linesize[3];
490cabdff1aSopenharmony_ci                }
491cabdff1aSopenharmony_ci            }
492cabdff1aSopenharmony_ci        } else {
493cabdff1aSopenharmony_ci            for (y = 0; y < s->height; y++) {
494cabdff1aSopenharmony_ci                for (x = 0; x < s->width; x++) {
495cabdff1aSopenharmony_ci                    int64_t k = AV_RB16(&src[3][x * 2]);
496cabdff1aSopenharmony_ci                    int64_t r = AV_RB16(&src[0][x * 2]) * k;
497cabdff1aSopenharmony_ci                    int64_t g = AV_RB16(&src[1][x * 2]) * k;
498cabdff1aSopenharmony_ci                    int64_t b = AV_RB16(&src[2][x * 2]) * k;
499cabdff1aSopenharmony_ci                    AV_WB16(&dst[0][x * 2], g * 65537 >> 32);
500cabdff1aSopenharmony_ci                    AV_WB16(&dst[1][x * 2], b * 65537 >> 32);
501cabdff1aSopenharmony_ci                    AV_WB16(&dst[2][x * 2], r * 65537 >> 32);
502cabdff1aSopenharmony_ci                }
503cabdff1aSopenharmony_ci                dst[0] += picture->linesize[0];
504cabdff1aSopenharmony_ci                dst[1] += picture->linesize[1];
505cabdff1aSopenharmony_ci                dst[2] += picture->linesize[2];
506cabdff1aSopenharmony_ci                src[0] += s->line_size;
507cabdff1aSopenharmony_ci                src[1] += s->line_size;
508cabdff1aSopenharmony_ci                src[2] += s->line_size;
509cabdff1aSopenharmony_ci                src[3] += s->line_size;
510cabdff1aSopenharmony_ci            }
511cabdff1aSopenharmony_ci            if (avctx->pix_fmt == AV_PIX_FMT_GBRAP16BE) {
512cabdff1aSopenharmony_ci                for (y = 0; y < s->height; y++) {
513cabdff1aSopenharmony_ci                    memcpy(dst[3], src[4], s->line_size);
514cabdff1aSopenharmony_ci                    src[4] += s->line_size;
515cabdff1aSopenharmony_ci                    dst[3] += picture->linesize[3];
516cabdff1aSopenharmony_ci                }
517cabdff1aSopenharmony_ci            }
518cabdff1aSopenharmony_ci        }
519cabdff1aSopenharmony_ci    } else {/* Planar */
520cabdff1aSopenharmony_ci        if (s->channel_count == 1)/* gray 8 or gray 16be */
521cabdff1aSopenharmony_ci            eq_channel[0] = 0;/* assign first channel, to first plane */
522cabdff1aSopenharmony_ci
523cabdff1aSopenharmony_ci        for (c = 0; c < s->channel_count; c++) {
524cabdff1aSopenharmony_ci            plane_number = eq_channel[c];
525cabdff1aSopenharmony_ci            ptr = picture->data[plane_number];/* get the right plane */
526cabdff1aSopenharmony_ci            for (y = 0; y < s->height; y++) {
527cabdff1aSopenharmony_ci                memcpy(ptr, ptr_data, s->line_size);
528cabdff1aSopenharmony_ci                ptr += picture->linesize[plane_number];
529cabdff1aSopenharmony_ci                ptr_data += s->line_size;
530cabdff1aSopenharmony_ci            }
531cabdff1aSopenharmony_ci        }
532cabdff1aSopenharmony_ci    }
533cabdff1aSopenharmony_ci
534cabdff1aSopenharmony_ci    if (s->color_mode == PSD_INDEXED) {
535cabdff1aSopenharmony_ci        picture->palette_has_changed = 1;
536cabdff1aSopenharmony_ci        memcpy(picture->data[1], s->palette, AVPALETTE_SIZE);
537cabdff1aSopenharmony_ci    }
538cabdff1aSopenharmony_ci
539cabdff1aSopenharmony_ci    av_freep(&s->tmp);
540cabdff1aSopenharmony_ci
541cabdff1aSopenharmony_ci    picture->pict_type = AV_PICTURE_TYPE_I;
542cabdff1aSopenharmony_ci    *got_frame = 1;
543cabdff1aSopenharmony_ci
544cabdff1aSopenharmony_ci    return avpkt->size;
545cabdff1aSopenharmony_ci}
546cabdff1aSopenharmony_ci
547cabdff1aSopenharmony_ciconst FFCodec ff_psd_decoder = {
548cabdff1aSopenharmony_ci    .p.name           = "psd",
549cabdff1aSopenharmony_ci    .p.long_name      = NULL_IF_CONFIG_SMALL("Photoshop PSD file"),
550cabdff1aSopenharmony_ci    .p.type           = AVMEDIA_TYPE_VIDEO,
551cabdff1aSopenharmony_ci    .p.id             = AV_CODEC_ID_PSD,
552cabdff1aSopenharmony_ci    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
553cabdff1aSopenharmony_ci    .priv_data_size   = sizeof(PSDContext),
554cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(decode_frame),
555cabdff1aSopenharmony_ci};
556