Browse code

libavcodec : add decoder for Photoshop PSD image files

Decode the Image Data Section (which contains merged pictures).
Support RGB/A and Grayscale/A in 8bits and 16 bits per channel.
Support uncompress and rle decompression in Image Data Section.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Martin Vignali authored on 2016/11/25 05:26:42
Showing 7 changed files
... ...
@@ -8,6 +8,7 @@ version <next>:
8 8
 - premultiply video filter
9 9
 - Support for spherical videos
10 10
 - configure now fails if autodetect-libraries are requested but not found
11
+- PSD Decoder
11 12
 
12 13
 version 3.2:
13 14
 - libopenmpt demuxer
... ...
@@ -584,6 +584,8 @@ following image formats are supported:
584 584
 @item PNG          @tab X @tab X
585 585
 @item PPM          @tab X @tab X
586 586
     @tab Portable PixelMap image
587
+@item PSD          @tab   @tab X
588
+    @tab Photoshop
587 589
 @item PTX          @tab   @tab X
588 590
     @tab V.Flash PTX format
589 591
 @item SGI          @tab X @tab X
... ...
@@ -462,6 +462,7 @@ OBJS-$(CONFIG_PRORES_LGPL_DECODER)     += proresdec_lgpl.o proresdsp.o proresdat
462 462
 OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc_anatoliy.o
463 463
 OBJS-$(CONFIG_PRORES_AW_ENCODER)       += proresenc_anatoliy.o
464 464
 OBJS-$(CONFIG_PRORES_KS_ENCODER)       += proresenc_kostya.o proresdata.o
465
+OBJS-$(CONFIG_PSD_DECODER)             += psd.o
465 466
 OBJS-$(CONFIG_PTX_DECODER)             += ptx.o
466 467
 OBJS-$(CONFIG_QCELP_DECODER)           += qcelpdec.o                     \
467 468
                                           celp_filters.o acelp_vectors.o \
... ...
@@ -287,6 +287,7 @@ void avcodec_register_all(void)
287 287
     REGISTER_ENCODER(PRORES_AW,         prores_aw);
288 288
     REGISTER_ENCODER(PRORES_KS,         prores_ks);
289 289
     REGISTER_DECODER(PRORES_LGPL,       prores_lgpl);
290
+    REGISTER_DECODER(PSD,               psd);
290 291
     REGISTER_DECODER(PTX,               ptx);
291 292
     REGISTER_DECODER(QDRAW,             qdraw);
292 293
     REGISTER_DECODER(QPEG,              qpeg);
... ...
@@ -411,6 +411,7 @@ enum AVCodecID {
411 411
     AV_CODEC_ID_MAGICYUV,
412 412
     AV_CODEC_ID_SHEERVIDEO,
413 413
     AV_CODEC_ID_YLC,
414
+    AV_CODEC_ID_PSD,
414 415
 
415 416
     /* various PCM "codecs" */
416 417
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
... ...
@@ -1461,6 +1461,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
1461 1461
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
1462 1462
     },
1463 1463
     {
1464
+        .id        = AV_CODEC_ID_PSD,
1465
+        .type      = AVMEDIA_TYPE_VIDEO,
1466
+        .name      = "psd",
1467
+        .long_name = NULL_IF_CONFIG_SMALL("Photoshop PSD file"),
1468
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
1469
+    },
1470
+    {
1464 1471
         .id        = AV_CODEC_ID_PTX,
1465 1472
         .type      = AVMEDIA_TYPE_VIDEO,
1466 1473
         .name      = "ptx",
1467 1474
new file mode 100644
... ...
@@ -0,0 +1,435 @@
0
+/*
1
+ * Photoshop (PSD) image decoder
2
+ * Copyright (c) 2016 Jokyo Images
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "bytestream.h"
22
+#include "internal.h"
23
+
24
+enum PsdCompr {
25
+    PSD_RAW,
26
+    PSD_RLE,
27
+    PSD_ZIP_WITHOUT_P,
28
+    PSD_ZIP_WITH_P,
29
+};
30
+
31
+enum PsdColorMode {
32
+    PSD_BITMAP,
33
+    PSD_GRAYSCALE,
34
+    PSD_INDEXED,
35
+    PSD_RGB,
36
+    PSD_CMYK,
37
+    PSD_MULTICHANNEL,
38
+    PSD_DUOTONE,
39
+    PSD_LAB,
40
+};
41
+
42
+typedef struct PSDContext {
43
+    AVClass *class;
44
+    AVFrame *picture;
45
+    AVCodecContext *avctx;
46
+    GetByteContext gb;
47
+
48
+    uint8_t * tmp;
49
+
50
+    uint16_t channel_count;
51
+    uint16_t channel_depth;
52
+
53
+    uint64_t uncompressed_size;
54
+    unsigned int pixel_size;/* 1 for 8 bits, 2 for 16 bits */
55
+    uint64_t line_size;/* length of src data (even width) */
56
+
57
+    int width;
58
+    int height;
59
+
60
+    enum PsdCompr compression;
61
+    enum PsdColorMode color_mode;
62
+} PSDContext;
63
+
64
+static int decode_header(PSDContext * s)
65
+{
66
+    int signature, version, color_mode, compression;
67
+    int64_t len_section;
68
+    int ret = 0;
69
+
70
+    if (bytestream2_get_bytes_left(&s->gb) < 30) {/* File header section + color map data section length */
71
+        av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");
72
+        return AVERROR_INVALIDDATA;
73
+    }
74
+
75
+    signature = bytestream2_get_le32(&s->gb);
76
+    if (signature != MKTAG('8','B','P','S')) {
77
+        av_log(s->avctx, AV_LOG_ERROR, "Wrong signature %d.\n", signature);
78
+        return AVERROR_INVALIDDATA;
79
+    }
80
+
81
+    version = bytestream2_get_be16(&s->gb);
82
+    if (version != 1) {
83
+        av_log(s->avctx, AV_LOG_ERROR, "Wrong version %d.\n", version);
84
+        return AVERROR_INVALIDDATA;
85
+    }
86
+
87
+    bytestream2_skip(&s->gb, 6);/* reserved */
88
+
89
+    s->channel_count = bytestream2_get_be16(&s->gb);
90
+    if ((s->channel_count < 1) || (s->channel_count > 56)) {
91
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid channel count %d.\n", s->channel_count);
92
+        return AVERROR_INVALIDDATA;
93
+    }
94
+
95
+    s->height = bytestream2_get_be32(&s->gb);
96
+
97
+    if ((s->height > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
98
+        av_log(s->avctx, AV_LOG_ERROR,
99
+               "Height > 30000 is experimental, add "
100
+               "'-strict %d' if you want to try to decode the picture.\n",
101
+               FF_COMPLIANCE_EXPERIMENTAL);
102
+        return AVERROR_EXPERIMENTAL;
103
+    }
104
+
105
+    s->width = bytestream2_get_be32(&s->gb);
106
+    if ((s->width > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
107
+        av_log(s->avctx, AV_LOG_ERROR,
108
+               "Width > 30000 is experimental, add "
109
+               "'-strict %d' if you want to try to decode the picture.\n",
110
+               FF_COMPLIANCE_EXPERIMENTAL);
111
+        return AVERROR_EXPERIMENTAL;
112
+    }
113
+
114
+    if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
115
+        return ret;
116
+
117
+    s->channel_depth = bytestream2_get_be16(&s->gb);
118
+
119
+    color_mode = bytestream2_get_be16(&s->gb);
120
+    switch (color_mode) {
121
+    case 0:
122
+        s->color_mode = PSD_BITMAP;
123
+        break;
124
+    case 1:
125
+        s->color_mode = PSD_GRAYSCALE;
126
+        break;
127
+    case 2:
128
+        s->color_mode = PSD_INDEXED;
129
+        break;
130
+    case 3:
131
+        s->color_mode = PSD_RGB;
132
+        break;
133
+    case 4:
134
+        s->color_mode = PSD_CMYK;
135
+        break;
136
+    case 7:
137
+        s->color_mode = PSD_MULTICHANNEL;
138
+        break;
139
+    case 8:
140
+        s->color_mode = PSD_DUOTONE;
141
+        break;
142
+    case 9:
143
+        s->color_mode = PSD_LAB;
144
+        break;
145
+    default:
146
+        av_log(s->avctx, AV_LOG_ERROR, "Unknown color mode %d.\n", color_mode);
147
+        return AVERROR_INVALIDDATA;
148
+    }
149
+
150
+    /* color map data */
151
+    len_section = bytestream2_get_be32(&s->gb);
152
+    if (len_section < 0) {
153
+        av_log(s->avctx, AV_LOG_ERROR, "Negative size for color map data section.\n");
154
+        return AVERROR_INVALIDDATA;
155
+    }
156
+
157
+    if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
158
+        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
159
+        return AVERROR_INVALIDDATA;
160
+    }
161
+    bytestream2_skip(&s->gb, len_section);
162
+
163
+    /* image ressources */
164
+    len_section = bytestream2_get_be32(&s->gb);
165
+    if (len_section < 0) {
166
+        av_log(s->avctx, AV_LOG_ERROR, "Negative size for image ressources section.\n");
167
+        return AVERROR_INVALIDDATA;
168
+    }
169
+
170
+    if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
171
+        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
172
+        return AVERROR_INVALIDDATA;
173
+    }
174
+    bytestream2_skip(&s->gb, len_section);
175
+
176
+    /* layers and masks */
177
+    len_section = bytestream2_get_be32(&s->gb);
178
+    if (len_section < 0) {
179
+        av_log(s->avctx, AV_LOG_ERROR, "Negative size for layers and masks data section.\n");
180
+        return AVERROR_INVALIDDATA;
181
+    }
182
+
183
+    if (bytestream2_get_bytes_left(&s->gb) < len_section) {
184
+        av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
185
+        return AVERROR_INVALIDDATA;
186
+    }
187
+    bytestream2_skip(&s->gb, len_section);
188
+
189
+    /* image section */
190
+    if (bytestream2_get_bytes_left(&s->gb) < 2) {
191
+        av_log(s->avctx, AV_LOG_ERROR, "File without image data section.\n");
192
+        return AVERROR_INVALIDDATA;
193
+    }
194
+
195
+    s->compression = bytestream2_get_be16(&s->gb);
196
+    switch (s->compression) {
197
+    case 0:
198
+    case 1:
199
+        break;
200
+    case 2:
201
+        avpriv_request_sample(s->avctx, "ZIP without predictor compression");
202
+        return AVERROR_PATCHWELCOME;
203
+        break;
204
+    case 3:
205
+        avpriv_request_sample(s->avctx, "ZIP with predictor compression");
206
+        return AVERROR_PATCHWELCOME;
207
+        break;
208
+    default:
209
+        av_log(s->avctx, AV_LOG_ERROR, "Unknown compression %d.\n", compression);
210
+        return AVERROR_INVALIDDATA;
211
+    }
212
+
213
+    return ret;
214
+}
215
+
216
+static int decode_rle(PSDContext * s){
217
+    unsigned int scanline_count;
218
+    unsigned int sl, count;
219
+    unsigned long target_index = 0;
220
+    unsigned int p;
221
+    int8_t rle_char;
222
+    unsigned int repeat_count;
223
+    uint8_t v;
224
+
225
+    scanline_count = s->height * s->channel_count;
226
+
227
+    /* scanline table */
228
+    if (bytestream2_get_bytes_left(&s->gb) < scanline_count * 2) {
229
+        av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline table.\n");
230
+        return AVERROR_INVALIDDATA;
231
+    }
232
+    bytestream2_skip(&s->gb, scanline_count * 2);/* size of each scanline */
233
+
234
+    /* decode rle data scanline by scanline */
235
+    for (sl = 0; sl < scanline_count; sl++) {
236
+        count = 0;
237
+
238
+        while (count < s->line_size) {
239
+            rle_char = bytestream2_get_byte(&s->gb);
240
+
241
+            if (rle_char <= 0) {/* byte repeat */
242
+                repeat_count = rle_char * -1;
243
+
244
+                if (bytestream2_get_bytes_left(&s->gb) < 1) {
245
+                    av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
246
+                    return AVERROR_INVALIDDATA;
247
+                }
248
+
249
+                if (target_index + repeat_count >= s->uncompressed_size) {
250
+                    av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
251
+                    return AVERROR_INVALIDDATA;
252
+                }
253
+
254
+                v = bytestream2_get_byte(&s->gb);
255
+                for (p = 0; p <= repeat_count; p++) {
256
+                    s->tmp[target_index++] = v;
257
+                }
258
+                count += repeat_count + 1;
259
+            } else {
260
+                if (bytestream2_get_bytes_left(&s->gb) < rle_char) {
261
+                    av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
262
+                    return AVERROR_INVALIDDATA;
263
+                }
264
+
265
+                if (target_index + rle_char >= s->uncompressed_size) {
266
+                    av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
267
+                    return AVERROR_INVALIDDATA;
268
+                }
269
+
270
+                for (p = 0; p <= rle_char; p++) {
271
+                    v = bytestream2_get_byte(&s->gb);
272
+                    s->tmp[target_index++] = v;
273
+                }
274
+                count += rle_char + 1;
275
+            }
276
+        }
277
+    }
278
+
279
+    return 0;
280
+}
281
+
282
+static int decode_frame(AVCodecContext *avctx, void *data,
283
+                        int *got_frame, AVPacket *avpkt)
284
+{
285
+    int ret;
286
+    uint8_t *ptr;
287
+    const uint8_t *ptr_data;
288
+    int index_out, c, y, x, p;
289
+    uint8_t eq_channel[4] = {2,0,1,3};/* RGBA -> GBRA channel order */
290
+    uint8_t plane_number;
291
+
292
+    AVFrame *picture = data;
293
+
294
+    PSDContext *s = avctx->priv_data;
295
+    s->avctx     = avctx;
296
+    s->channel_count = 0;
297
+    s->channel_depth = 0;
298
+    s->tmp           = NULL;
299
+    s->line_size     = 0;
300
+
301
+    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
302
+
303
+    if ((ret = decode_header(s)) < 0)
304
+        return ret;
305
+
306
+    s->pixel_size = s->channel_depth >> 3;/* in byte */
307
+    s->line_size = s->width * s->pixel_size;
308
+    s->uncompressed_size = s->line_size * s->height * s->channel_count;
309
+
310
+    switch (s->color_mode) {
311
+    case PSD_RGB:
312
+        if (s->channel_count == 3) {
313
+            if (s->channel_depth == 8) {
314
+                avctx->pix_fmt = AV_PIX_FMT_GBRP;
315
+            } else if (s->channel_depth == 16) {
316
+                avctx->pix_fmt = AV_PIX_FMT_GBRP16BE;
317
+            } else {
318
+                avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
319
+                return AVERROR_PATCHWELCOME;
320
+            }
321
+        } else if (s->channel_count == 4) {
322
+            if (s->channel_depth == 8) {
323
+                avctx->pix_fmt = AV_PIX_FMT_GBRAP;
324
+            } else if (s->channel_depth == 16) {
325
+                avctx->pix_fmt = AV_PIX_FMT_GBRAP16BE;
326
+            } else {
327
+                avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
328
+                return AVERROR_PATCHWELCOME;
329
+            }
330
+        } else {
331
+            avpriv_report_missing_feature(avctx, "channel count %d for rgb", s->channel_count);
332
+            return AVERROR_PATCHWELCOME;
333
+        }
334
+        break;
335
+    case PSD_GRAYSCALE:
336
+        if (s->channel_count == 1) {
337
+            if (s->channel_depth == 8) {
338
+                avctx->pix_fmt = AV_PIX_FMT_GRAY8;
339
+            } else if (s->channel_depth == 16) {
340
+                avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
341
+            } else {
342
+                avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
343
+                return AVERROR_PATCHWELCOME;
344
+            }
345
+        } else if (s->channel_count == 2) {
346
+            if (s->channel_depth == 8) {
347
+                avctx->pix_fmt = AV_PIX_FMT_YA8;
348
+            } else if (s->channel_depth == 16) {
349
+                avctx->pix_fmt = AV_PIX_FMT_YA16BE;
350
+            } else {
351
+                avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
352
+                return AVERROR_PATCHWELCOME;
353
+            }
354
+        } else {
355
+            avpriv_report_missing_feature(avctx, "channel count %d for grayscale", s->channel_count);
356
+            return AVERROR_PATCHWELCOME;
357
+        }
358
+        break;
359
+    default:
360
+        avpriv_report_missing_feature(avctx, "color mode %d", s->color_mode);
361
+        return AVERROR_PATCHWELCOME;
362
+    }
363
+
364
+    if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
365
+        return ret;
366
+
367
+    /* decode picture if need */
368
+    if (s->compression == PSD_RLE) {
369
+        s->tmp = av_malloc(s->uncompressed_size);
370
+        if (!s->tmp)
371
+            return AVERROR(ENOMEM);
372
+
373
+        ret = decode_rle(s);
374
+
375
+        if (ret < 0) {
376
+            av_freep(&s->tmp);
377
+            return ret;
378
+        }
379
+
380
+        ptr_data = s->tmp;
381
+    } else {
382
+        if (bytestream2_get_bytes_left(&s->gb) < s->uncompressed_size) {
383
+            av_log(s->avctx, AV_LOG_ERROR, "Not enough data for raw image data section.\n");
384
+            return AVERROR_INVALIDDATA;
385
+        }
386
+        ptr_data = s->gb.buffer;
387
+    }
388
+
389
+    /* Store data */
390
+    if ((avctx->pix_fmt == AV_PIX_FMT_YA8)||(avctx->pix_fmt == AV_PIX_FMT_YA16BE)){/* Interleaved */
391
+        ptr = picture->data[0];
392
+        for (c = 0; c < s->channel_count; c++) {
393
+            for (y = 0; y < s->height; y++) {
394
+                for (x = 0; x < s->width; x++) {
395
+                    index_out = y * picture->linesize[0] + x * s->channel_count * s->pixel_size + c * s->pixel_size;
396
+                    for (p = 0; p < s->pixel_size; p++) {
397
+                        ptr[index_out + p] = *ptr_data;
398
+                        ptr_data ++;
399
+                    }
400
+                }
401
+            }
402
+        }
403
+    } else {/* Planar */
404
+        if (s->channel_count == 1)/* gray 8 or gray 16be */
405
+            eq_channel[0] = 0;/* assign first channel, to first plane */
406
+
407
+        for (c = 0; c < s->channel_count; c++) {
408
+            plane_number = eq_channel[c];
409
+            ptr = picture->data[plane_number];/* get the right plane */
410
+            for (y = 0; y < s->height; y++) {
411
+                memcpy(ptr, ptr_data, s->width * s->pixel_size);
412
+                ptr += picture->linesize[plane_number];
413
+                ptr_data += s->width * s->pixel_size;
414
+            }
415
+        }
416
+    }
417
+
418
+    av_freep(&s->tmp);
419
+
420
+    picture->pict_type = AV_PICTURE_TYPE_I;
421
+    *got_frame = 1;
422
+
423
+    return avpkt->size;
424
+}
425
+
426
+AVCodec ff_psd_decoder = {
427
+    .name             = "psd",
428
+    .long_name        = NULL_IF_CONFIG_SMALL("Photoshop PSD file"),
429
+    .type             = AVMEDIA_TYPE_VIDEO,
430
+    .id               = AV_CODEC_ID_PSD,
431
+    .priv_data_size   = sizeof(PSDContext),
432
+    .decode           = decode_frame,
433
+    .capabilities     = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
434
+};