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