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
24
30 };
31
41 };
42
48
50
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
60
63
66
68 {
70 int64_t len_section;
71 int ret = 0;
72
76 }
77
78 signature = bytestream2_get_le32(&s->
gb);
79 if (signature !=
MKTAG(
'8',
'B',
'P',
'S')) {
82 }
83
84 version = bytestream2_get_be16(&s->
gb);
85 if (version != 1) {
88 }
89
91
96 }
97
98 s->
height = bytestream2_get_be32(&s->
gb);
99
102 "Height > 30000 is experimental, add "
103 "'-strict %d' if you want to try to decode the picture.\n",
106 }
107
108 s->
width = bytestream2_get_be32(&s->
gb);
111 "Width > 30000 is experimental, add "
112 "'-strict %d' if you want to try to decode the picture.\n",
115 }
116
118 return ret;
119
121
122 color_mode = bytestream2_get_be16(&s->
gb);
123 switch (color_mode) {
124 case 0:
126 break;
127 case 1:
129 break;
130 case 2:
132 break;
133 case 3:
135 break;
136 case 4:
138 break;
139 case 7:
141 break;
142 case 8:
144 break;
145 case 9:
147 break;
148 default:
151 }
152
153 /* color map data */
154 len_section = bytestream2_get_be32(&s->
gb);
155 if (len_section < 0) {
158 }
159
163 }
164 if (len_section) {
165 int i,j;
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 }
173
174 /* image ressources */
175 len_section = bytestream2_get_be32(&s->
gb);
176 if (len_section < 0) {
179 }
180
184 }
186
187 /* layers and masks */
188 len_section = bytestream2_get_be32(&s->
gb);
189 if (len_section < 0) {
192 }
193
197 }
199
200 /* image section */
204 }
205
208 case 0:
209 case 1:
210 break;
211 case 2:
214 break;
215 case 3:
218 break;
219 default:
222 }
223
224 return ret;
225 }
226
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;
235
237
238 /* scanline table */
242 }
244
245 /* decode rle data scanline by scanline */
246 for (sl = 0; sl < scanline_count; sl++) {
247 count = 0;
248
250 rle_char = bytestream2_get_byte(&s->
gb);
251
252 if (rle_char <= 0) {/* byte repeat */
253 repeat_count = rle_char * -1;
254
258 }
259
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 {
274 }
275
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
295 {
296 int ret;
299 int index_out,
c, y, x, p;
300 uint8_t eq_channel[4] = {2,0,1,3};
/* RGBA -> GBRA channel order */
302
304
311
313
315 return ret;
316
319
324 "Invalid bitmap file (channel_depth %d, channel_count %d)\n",
327 }
330 break;
334 "Invalid indexed file (channel_depth %d, channel_count %d)\n",
337 }
339 break;
346 } else {
349 }
355 } else {
358 }
359 } else {
362 }
363 break;
372 } else {
375 }
381 } else {
384 }
385 } else {
388 }
389 break;
390 default:
393 }
394
396
398 return ret;
399
400 /* decode picture if need */
405
407
408 if (ret < 0) {
410 return ret;
411 }
412
414 } else {
418 }
420 }
421
422 /* Store data */
424 ptr = picture->
data[0];
426 for (y = 0; y < s->
height; y++) {
427 for (x = 0; x < s->
width; x++) {
430 ptr[index_out + p] = *ptr_data;
431 ptr_data ++;
432 }
433 }
434 }
435 }
436 } else {/* Planar */
438 eq_channel[0] = 0;/* assign first channel, to first plane */
439
441 plane_number = eq_channel[
c];
442 ptr = picture->
data[plane_number];
/* get the right plane */
443 for (y = 0; y < s->
height; y++) {
445 ptr += picture->
linesize[plane_number];
447 }
448 }
449 }
450
454 }
455
457
459 *got_frame = 1;
460
462 }
463
472 };
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
8 bits gray, 8 bits alpha
#define AV_LOG_WARNING
Something somehow does not look correct.
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.
static int decode_rle(PSDContext *s)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
planar GBRA 4:4:4:4 64bpp, big-endian
static const char signature[]
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
8 bits with AV_PIX_FMT_RGB32 palette
static int decode_header(PSDContext *s)
planar GBR 4:4:4 48bpp, big-endian
enum PsdCompr compression
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
16 bits gray, 16 bits alpha (big-endian)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
uint64_t uncompressed_size
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
const char * name
Name of the codec implementation.
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
enum AVPictureType pict_type
Picture type of the frame.
enum PsdColorMode color_mode
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it...
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
uint8_t palette[AVPALETTE_SIZE]
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Describe the class of an AVClass context structure.
int palette_has_changed
Tell user application that palette has changed from previous frame.
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.
common internal api header.
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
planar GBRA 4:4:4:4 32bpp
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define MKTAG(a, b, c, d)
This structure stores compressed data.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).