FFmpeg  4.0
psd.c
Go to the documentation of this file.
1 /*
2  * Photoshop (PSD) image decoder
3  * Copyright (c) 2016 Jokyo Images
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "bytestream.h"
23 #include "internal.h"
24 
25 enum PsdCompr {
30 };
31 
41 };
42 
43 typedef struct PSDContext {
44  AVClass *class;
48 
50 
51  uint16_t channel_count;
52  uint16_t channel_depth;
53 
55  unsigned int pixel_size;/* 1 for 8 bits, 2 for 16 bits */
56  uint64_t line_size;/* length of src data (even width) */
57 
58  int width;
59  int height;
60 
63 
65 } PSDContext;
66 
67 static int decode_header(PSDContext * s)
68 {
70  int64_t len_section;
71  int ret = 0;
72 
73  if (bytestream2_get_bytes_left(&s->gb) < 30) {/* File header section + color map data section length */
74  av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");
75  return AVERROR_INVALIDDATA;
76  }
77 
78  signature = bytestream2_get_le32(&s->gb);
79  if (signature != MKTAG('8','B','P','S')) {
80  av_log(s->avctx, AV_LOG_ERROR, "Wrong signature %d.\n", signature);
81  return AVERROR_INVALIDDATA;
82  }
83 
84  version = bytestream2_get_be16(&s->gb);
85  if (version != 1) {
86  av_log(s->avctx, AV_LOG_ERROR, "Wrong version %d.\n", version);
87  return AVERROR_INVALIDDATA;
88  }
89 
90  bytestream2_skip(&s->gb, 6);/* reserved */
91 
92  s->channel_count = bytestream2_get_be16(&s->gb);
93  if ((s->channel_count < 1) || (s->channel_count > 56)) {
94  av_log(s->avctx, AV_LOG_ERROR, "Invalid channel count %d.\n", s->channel_count);
95  return AVERROR_INVALIDDATA;
96  }
97 
98  s->height = bytestream2_get_be32(&s->gb);
99 
100  if ((s->height > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
102  "Height > 30000 is experimental, add "
103  "'-strict %d' if you want to try to decode the picture.\n",
105  return AVERROR_EXPERIMENTAL;
106  }
107 
108  s->width = bytestream2_get_be32(&s->gb);
109  if ((s->width > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
111  "Width > 30000 is experimental, add "
112  "'-strict %d' if you want to try to decode the picture.\n",
114  return AVERROR_EXPERIMENTAL;
115  }
116 
117  if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
118  return ret;
119 
120  s->channel_depth = bytestream2_get_be16(&s->gb);
121 
122  color_mode = bytestream2_get_be16(&s->gb);
123  switch (color_mode) {
124  case 0:
125  s->color_mode = PSD_BITMAP;
126  break;
127  case 1:
129  break;
130  case 2:
131  s->color_mode = PSD_INDEXED;
132  break;
133  case 3:
134  s->color_mode = PSD_RGB;
135  break;
136  case 4:
137  s->color_mode = PSD_CMYK;
138  break;
139  case 7:
141  break;
142  case 8:
143  s->color_mode = PSD_DUOTONE;
144  break;
145  case 9:
146  s->color_mode = PSD_LAB;
147  break;
148  default:
149  av_log(s->avctx, AV_LOG_ERROR, "Unknown color mode %d.\n", color_mode);
150  return AVERROR_INVALIDDATA;
151  }
152 
153  /* color map data */
154  len_section = bytestream2_get_be32(&s->gb);
155  if (len_section < 0) {
156  av_log(s->avctx, AV_LOG_ERROR, "Negative size for color map data section.\n");
157  return AVERROR_INVALIDDATA;
158  }
159 
160  if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
161  av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
162  return AVERROR_INVALIDDATA;
163  }
164  if (len_section) {
165  int i,j;
166  memset(s->palette, 0xff, AVPALETTE_SIZE);
167  for (j = HAVE_BIGENDIAN; j < 3 + HAVE_BIGENDIAN; j++)
168  for (i = 0; i < FFMIN(256, len_section / 3); i++)
169  s->palette[i * 4 + (HAVE_BIGENDIAN ? j : 2 - j)] = bytestream2_get_byteu(&s->gb);
170  len_section -= i * 3;
171  }
172  bytestream2_skip(&s->gb, len_section);
173 
174  /* image ressources */
175  len_section = bytestream2_get_be32(&s->gb);
176  if (len_section < 0) {
177  av_log(s->avctx, AV_LOG_ERROR, "Negative size for image ressources section.\n");
178  return AVERROR_INVALIDDATA;
179  }
180 
181  if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
182  av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
183  return AVERROR_INVALIDDATA;
184  }
185  bytestream2_skip(&s->gb, len_section);
186 
187  /* layers and masks */
188  len_section = bytestream2_get_be32(&s->gb);
189  if (len_section < 0) {
190  av_log(s->avctx, AV_LOG_ERROR, "Negative size for layers and masks data section.\n");
191  return AVERROR_INVALIDDATA;
192  }
193 
194  if (bytestream2_get_bytes_left(&s->gb) < len_section) {
195  av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
196  return AVERROR_INVALIDDATA;
197  }
198  bytestream2_skip(&s->gb, len_section);
199 
200  /* image section */
201  if (bytestream2_get_bytes_left(&s->gb) < 2) {
202  av_log(s->avctx, AV_LOG_ERROR, "File without image data section.\n");
203  return AVERROR_INVALIDDATA;
204  }
205 
206  s->compression = bytestream2_get_be16(&s->gb);
207  switch (s->compression) {
208  case 0:
209  case 1:
210  break;
211  case 2:
212  avpriv_request_sample(s->avctx, "ZIP without predictor compression");
213  return AVERROR_PATCHWELCOME;
214  break;
215  case 3:
216  avpriv_request_sample(s->avctx, "ZIP with predictor compression");
217  return AVERROR_PATCHWELCOME;
218  break;
219  default:
220  av_log(s->avctx, AV_LOG_ERROR, "Unknown compression %d.\n", s->compression);
221  return AVERROR_INVALIDDATA;
222  }
223 
224  return ret;
225 }
226 
227 static int decode_rle(PSDContext * s){
228  unsigned int scanline_count;
229  unsigned int sl, count;
230  unsigned long target_index = 0;
231  unsigned int p;
232  int8_t rle_char;
233  unsigned int repeat_count;
234  uint8_t v;
235 
236  scanline_count = s->height * s->channel_count;
237 
238  /* scanline table */
239  if (bytestream2_get_bytes_left(&s->gb) < scanline_count * 2) {
240  av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline table.\n");
241  return AVERROR_INVALIDDATA;
242  }
243  bytestream2_skip(&s->gb, scanline_count * 2);/* size of each scanline */
244 
245  /* decode rle data scanline by scanline */
246  for (sl = 0; sl < scanline_count; sl++) {
247  count = 0;
248 
249  while (count < s->line_size) {
250  rle_char = bytestream2_get_byte(&s->gb);
251 
252  if (rle_char <= 0) {/* byte repeat */
253  repeat_count = rle_char * -1;
254 
255  if (bytestream2_get_bytes_left(&s->gb) < 1) {
256  av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
257  return AVERROR_INVALIDDATA;
258  }
259 
260  if (target_index + repeat_count >= s->uncompressed_size) {
261  av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
262  return AVERROR_INVALIDDATA;
263  }
264 
265  v = bytestream2_get_byte(&s->gb);
266  for (p = 0; p <= repeat_count; p++) {
267  s->tmp[target_index++] = v;
268  }
269  count += repeat_count + 1;
270  } else {
271  if (bytestream2_get_bytes_left(&s->gb) < rle_char) {
272  av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
273  return AVERROR_INVALIDDATA;
274  }
275 
276  if (target_index + rle_char >= s->uncompressed_size) {
277  av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
278  return AVERROR_INVALIDDATA;
279  }
280 
281  for (p = 0; p <= rle_char; p++) {
282  v = bytestream2_get_byte(&s->gb);
283  s->tmp[target_index++] = v;
284  }
285  count += rle_char + 1;
286  }
287  }
288  }
289 
290  return 0;
291 }
292 
294  int *got_frame, AVPacket *avpkt)
295 {
296  int ret;
297  uint8_t *ptr;
298  const uint8_t *ptr_data;
299  int index_out, c, y, x, p;
300  uint8_t eq_channel[4] = {2,0,1,3};/* RGBA -> GBRA channel order */
301  uint8_t plane_number;
302 
303  AVFrame *picture = data;
304 
305  PSDContext *s = avctx->priv_data;
306  s->avctx = avctx;
307  s->channel_count = 0;
308  s->channel_depth = 0;
309  s->tmp = NULL;
310  s->line_size = 0;
311 
312  bytestream2_init(&s->gb, avpkt->data, avpkt->size);
313 
314  if ((ret = decode_header(s)) < 0)
315  return ret;
316 
317  s->pixel_size = s->channel_depth >> 3;/* in byte */
318  s->line_size = s->width * s->pixel_size;
319 
320  switch (s->color_mode) {
321  case PSD_BITMAP:
322  if (s->channel_depth != 1 || s->channel_count != 1) {
324  "Invalid bitmap file (channel_depth %d, channel_count %d)\n",
326  return AVERROR_INVALIDDATA;
327  }
328  s->line_size = s->width + 7 >> 3;
329  avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
330  break;
331  case PSD_INDEXED:
332  if (s->channel_depth != 8 || s->channel_count != 1) {
334  "Invalid indexed file (channel_depth %d, channel_count %d)\n",
336  return AVERROR_INVALIDDATA;
337  }
338  avctx->pix_fmt = AV_PIX_FMT_PAL8;
339  break;
340  case PSD_RGB:
341  if (s->channel_count == 3) {
342  if (s->channel_depth == 8) {
343  avctx->pix_fmt = AV_PIX_FMT_GBRP;
344  } else if (s->channel_depth == 16) {
345  avctx->pix_fmt = AV_PIX_FMT_GBRP16BE;
346  } else {
347  avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
348  return AVERROR_PATCHWELCOME;
349  }
350  } else if (s->channel_count == 4) {
351  if (s->channel_depth == 8) {
352  avctx->pix_fmt = AV_PIX_FMT_GBRAP;
353  } else if (s->channel_depth == 16) {
354  avctx->pix_fmt = AV_PIX_FMT_GBRAP16BE;
355  } else {
356  avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
357  return AVERROR_PATCHWELCOME;
358  }
359  } else {
360  avpriv_report_missing_feature(avctx, "channel count %d for rgb", s->channel_count);
361  return AVERROR_PATCHWELCOME;
362  }
363  break;
364  case PSD_DUOTONE:
365  av_log(avctx, AV_LOG_WARNING, "ignoring unknown duotone specification.\n");
366  case PSD_GRAYSCALE:
367  if (s->channel_count == 1) {
368  if (s->channel_depth == 8) {
369  avctx->pix_fmt = AV_PIX_FMT_GRAY8;
370  } else if (s->channel_depth == 16) {
371  avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
372  } else {
373  avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
374  return AVERROR_PATCHWELCOME;
375  }
376  } else if (s->channel_count == 2) {
377  if (s->channel_depth == 8) {
378  avctx->pix_fmt = AV_PIX_FMT_YA8;
379  } else if (s->channel_depth == 16) {
380  avctx->pix_fmt = AV_PIX_FMT_YA16BE;
381  } else {
382  avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
383  return AVERROR_PATCHWELCOME;
384  }
385  } else {
386  avpriv_report_missing_feature(avctx, "channel count %d for grayscale", s->channel_count);
387  return AVERROR_PATCHWELCOME;
388  }
389  break;
390  default:
391  avpriv_report_missing_feature(avctx, "color mode %d", s->color_mode);
392  return AVERROR_PATCHWELCOME;
393  }
394 
396 
397  if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
398  return ret;
399 
400  /* decode picture if need */
401  if (s->compression == PSD_RLE) {
403  if (!s->tmp)
404  return AVERROR(ENOMEM);
405 
406  ret = decode_rle(s);
407 
408  if (ret < 0) {
409  av_freep(&s->tmp);
410  return ret;
411  }
412 
413  ptr_data = s->tmp;
414  } else {
416  av_log(s->avctx, AV_LOG_ERROR, "Not enough data for raw image data section.\n");
417  return AVERROR_INVALIDDATA;
418  }
419  ptr_data = s->gb.buffer;
420  }
421 
422  /* Store data */
423  if ((avctx->pix_fmt == AV_PIX_FMT_YA8)||(avctx->pix_fmt == AV_PIX_FMT_YA16BE)){/* Interleaved */
424  ptr = picture->data[0];
425  for (c = 0; c < s->channel_count; c++) {
426  for (y = 0; y < s->height; y++) {
427  for (x = 0; x < s->width; x++) {
428  index_out = y * picture->linesize[0] + x * s->channel_count * s->pixel_size + c * s->pixel_size;
429  for (p = 0; p < s->pixel_size; p++) {
430  ptr[index_out + p] = *ptr_data;
431  ptr_data ++;
432  }
433  }
434  }
435  }
436  } else {/* Planar */
437  if (s->channel_count == 1)/* gray 8 or gray 16be */
438  eq_channel[0] = 0;/* assign first channel, to first plane */
439 
440  for (c = 0; c < s->channel_count; c++) {
441  plane_number = eq_channel[c];
442  ptr = picture->data[plane_number];/* get the right plane */
443  for (y = 0; y < s->height; y++) {
444  memcpy(ptr, ptr_data, s->line_size);
445  ptr += picture->linesize[plane_number];
446  ptr_data += s->line_size;
447  }
448  }
449  }
450 
451  if (s->color_mode == PSD_INDEXED) {
452  picture->palette_has_changed = 1;
453  memcpy(picture->data[1], s->palette, AVPALETTE_SIZE);
454  }
455 
456  av_freep(&s->tmp);
457 
458  picture->pict_type = AV_PICTURE_TYPE_I;
459  *got_frame = 1;
460 
461  return avpkt->size;
462 }
463 
465  .name = "psd",
466  .long_name = NULL_IF_CONFIG_SMALL("Photoshop PSD file"),
467  .type = AVMEDIA_TYPE_VIDEO,
468  .id = AV_CODEC_ID_PSD,
469  .priv_data_size = sizeof(PSDContext),
470  .decode = decode_frame,
472 };
Definition: psd.c:33
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: avcodec.h:2581
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
8 bits gray, 8 bits alpha
Definition: pixfmt.h:139
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:104
uint16_t channel_count
Definition: psd.c:51
static int decode_rle(PSDContext *s)
Definition: psd.c:227
uint16_t channel_depth
Definition: psd.c:52
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:164
int size
Definition: avcodec.h:1431
Definition: psd.c:37
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1727
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
int version
Definition: avisynth_c.h:766
AVCodec.
Definition: avcodec.h:3408
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
uint64_t line_size
Definition: psd.c:56
Definition: psd.c:27
planar GBRA 4:4:4:4 64bpp, big-endian
Definition: pixfmt.h:212
static const char signature[]
Definition: ipmovie.c:615
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t
#define av_malloc(s)
GetByteContext gb
Definition: psd.c:47
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:73
static int decode_header(PSDContext *s)
Definition: psd.c:67
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
Definition: psd.c:26
PsdCompr
Definition: psd.c:25
const char data[16]
Definition: mxf.c:90
uint8_t * data
Definition: avcodec.h:1430
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:170
const uint8_t * buffer
Definition: bytestream.h:34
AVFrame * picture
Definition: psd.c:45
#define av_log(a,...)
enum PsdCompr compression
Definition: psd.c:61
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
16 bits gray, 16 bits alpha (big-endian)
Definition: pixfmt.h:208
PsdColorMode
Definition: psd.c:32
#define AVERROR(e)
Definition: error.h:43
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
uint64_t uncompressed_size
Definition: psd.c:54
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
const char * name
Name of the codec implementation.
Definition: avcodec.h:3415
AVCodec ff_psd_decoder
Definition: psd.c:464
Definition: psd.c:43
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1015
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:301
#define FFMIN(a, b)
Definition: common.h:96
enum PsdColorMode color_mode
Definition: psd.c:62
unsigned int pixel_size
Definition: psd.c:55
Definition: psd.c:36
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it...
Definition: error.h:72
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
AVCodecContext * avctx
Definition: psd.c:46
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
uint8_t palette[AVPALETTE_SIZE]
Definition: psd.c:64
main external API structure.
Definition: avcodec.h:1518
int height
Definition: psd.c:59
uint8_t * tmp
Definition: psd.c:49
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1891
Describe the class of an AVClass context structure.
Definition: log.h:67
Y , 16bpp, big-endian.
Definition: pixfmt.h:93
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:375
int width
Definition: psd.c:58
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
Y , 8bpp.
Definition: pixfmt.h:70
common internal api header.
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:71
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:211
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: psd.c:293
static double c[64]
void * priv_data
Definition: avcodec.h:1545
Definition: psd.c:40
#define av_freep(p)
void INT64 INT64 count
Definition: avisynth_c.h:690
#define HAVE_BIGENDIAN
Definition: config.h:196
#define MKTAG(a, b, c, d)
Definition: common.h:366
This structure stores compressed data.
Definition: avcodec.h:1407
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:959
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition: avcodec.h:2576