LCOV - code coverage report
Current view: top level - libavcodec - psd.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 165 251 65.7 %
Date: 2017-12-16 21:16:39 Functions: 3 3 100.0 %

          Line data    Source code
       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 {
      26             :     PSD_RAW,
      27             :     PSD_RLE,
      28             :     PSD_ZIP_WITHOUT_P,
      29             :     PSD_ZIP_WITH_P,
      30             : };
      31             : 
      32             : enum PsdColorMode {
      33             :     PSD_BITMAP,
      34             :     PSD_GRAYSCALE,
      35             :     PSD_INDEXED,
      36             :     PSD_RGB,
      37             :     PSD_CMYK,
      38             :     PSD_MULTICHANNEL,
      39             :     PSD_DUOTONE,
      40             :     PSD_LAB,
      41             : };
      42             : 
      43             : typedef struct PSDContext {
      44             :     AVClass *class;
      45             :     AVFrame *picture;
      46             :     AVCodecContext *avctx;
      47             :     GetByteContext gb;
      48             : 
      49             :     uint8_t * tmp;
      50             : 
      51             :     uint16_t channel_count;
      52             :     uint16_t channel_depth;
      53             : 
      54             :     uint64_t uncompressed_size;
      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             : 
      61             :     enum PsdCompr compression;
      62             :     enum PsdColorMode color_mode;
      63             : 
      64             :     uint8_t palette[AVPALETTE_SIZE];
      65             : } PSDContext;
      66             : 
      67          30 : static int decode_header(PSDContext * s)
      68             : {
      69             :     int signature, version, color_mode;
      70             :     int64_t len_section;
      71          30 :     int ret = 0;
      72             : 
      73          30 :     if (bytestream2_get_bytes_left(&s->gb) < 30) {/* File header section + color map data section length */
      74           0 :         av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");
      75           0 :         return AVERROR_INVALIDDATA;
      76             :     }
      77             : 
      78          30 :     signature = bytestream2_get_le32(&s->gb);
      79          30 :     if (signature != MKTAG('8','B','P','S')) {
      80           0 :         av_log(s->avctx, AV_LOG_ERROR, "Wrong signature %d.\n", signature);
      81           0 :         return AVERROR_INVALIDDATA;
      82             :     }
      83             : 
      84          30 :     version = bytestream2_get_be16(&s->gb);
      85          30 :     if (version != 1) {
      86           0 :         av_log(s->avctx, AV_LOG_ERROR, "Wrong version %d.\n", version);
      87           0 :         return AVERROR_INVALIDDATA;
      88             :     }
      89             : 
      90          30 :     bytestream2_skip(&s->gb, 6);/* reserved */
      91             : 
      92          30 :     s->channel_count = bytestream2_get_be16(&s->gb);
      93          30 :     if ((s->channel_count < 1) || (s->channel_count > 56)) {
      94           0 :         av_log(s->avctx, AV_LOG_ERROR, "Invalid channel count %d.\n", s->channel_count);
      95           0 :         return AVERROR_INVALIDDATA;
      96             :     }
      97             : 
      98          30 :     s->height = bytestream2_get_be32(&s->gb);
      99             : 
     100          30 :     if ((s->height > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
     101           0 :         av_log(s->avctx, AV_LOG_ERROR,
     102             :                "Height > 30000 is experimental, add "
     103             :                "'-strict %d' if you want to try to decode the picture.\n",
     104             :                FF_COMPLIANCE_EXPERIMENTAL);
     105           0 :         return AVERROR_EXPERIMENTAL;
     106             :     }
     107             : 
     108          30 :     s->width = bytestream2_get_be32(&s->gb);
     109          30 :     if ((s->width > 30000) && (s->avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)) {
     110           0 :         av_log(s->avctx, AV_LOG_ERROR,
     111             :                "Width > 30000 is experimental, add "
     112             :                "'-strict %d' if you want to try to decode the picture.\n",
     113             :                FF_COMPLIANCE_EXPERIMENTAL);
     114           0 :         return AVERROR_EXPERIMENTAL;
     115             :     }
     116             : 
     117          30 :     if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
     118           0 :         return ret;
     119             : 
     120          30 :     s->channel_depth = bytestream2_get_be16(&s->gb);
     121             : 
     122          30 :     color_mode = bytestream2_get_be16(&s->gb);
     123          30 :     switch (color_mode) {
     124           2 :     case 0:
     125           2 :         s->color_mode = PSD_BITMAP;
     126           2 :         break;
     127           8 :     case 1:
     128           8 :         s->color_mode = PSD_GRAYSCALE;
     129           8 :         break;
     130           2 :     case 2:
     131           2 :         s->color_mode = PSD_INDEXED;
     132           2 :         break;
     133          16 :     case 3:
     134          16 :         s->color_mode = PSD_RGB;
     135          16 :         break;
     136           0 :     case 4:
     137           0 :         s->color_mode = PSD_CMYK;
     138           0 :         break;
     139           0 :     case 7:
     140           0 :         s->color_mode = PSD_MULTICHANNEL;
     141           0 :         break;
     142           2 :     case 8:
     143           2 :         s->color_mode = PSD_DUOTONE;
     144           2 :         break;
     145           0 :     case 9:
     146           0 :         s->color_mode = PSD_LAB;
     147           0 :         break;
     148           0 :     default:
     149           0 :         av_log(s->avctx, AV_LOG_ERROR, "Unknown color mode %d.\n", color_mode);
     150           0 :         return AVERROR_INVALIDDATA;
     151             :     }
     152             : 
     153             :     /* color map data */
     154          30 :     len_section = bytestream2_get_be32(&s->gb);
     155          30 :     if (len_section < 0) {
     156           0 :         av_log(s->avctx, AV_LOG_ERROR, "Negative size for color map data section.\n");
     157           0 :         return AVERROR_INVALIDDATA;
     158             :     }
     159             : 
     160          30 :     if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
     161           0 :         av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
     162           0 :         return AVERROR_INVALIDDATA;
     163             :     }
     164          30 :     if (len_section) {
     165             :         int i,j;
     166           4 :         memset(s->palette, 0xff, AVPALETTE_SIZE);
     167          16 :         for (j = HAVE_BIGENDIAN; j < 3 + HAVE_BIGENDIAN; j++)
     168        2592 :             for (i = 0; i < FFMIN(256, len_section / 3); i++)
     169        2580 :                 s->palette[i * 4 + (HAVE_BIGENDIAN ? j : 2 - j)] = bytestream2_get_byteu(&s->gb);
     170           4 :         len_section -= i * 3;
     171             :     }
     172          30 :     bytestream2_skip(&s->gb, len_section);
     173             : 
     174             :     /* image ressources */
     175          30 :     len_section = bytestream2_get_be32(&s->gb);
     176          30 :     if (len_section < 0) {
     177           0 :         av_log(s->avctx, AV_LOG_ERROR, "Negative size for image ressources section.\n");
     178           0 :         return AVERROR_INVALIDDATA;
     179             :     }
     180             : 
     181          30 :     if (bytestream2_get_bytes_left(&s->gb) < (len_section + 4)) { /* section and len next section */
     182           0 :         av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
     183           0 :         return AVERROR_INVALIDDATA;
     184             :     }
     185          30 :     bytestream2_skip(&s->gb, len_section);
     186             : 
     187             :     /* layers and masks */
     188          30 :     len_section = bytestream2_get_be32(&s->gb);
     189          30 :     if (len_section < 0) {
     190           0 :         av_log(s->avctx, AV_LOG_ERROR, "Negative size for layers and masks data section.\n");
     191           0 :         return AVERROR_INVALIDDATA;
     192             :     }
     193             : 
     194          30 :     if (bytestream2_get_bytes_left(&s->gb) < len_section) {
     195           0 :         av_log(s->avctx, AV_LOG_ERROR, "Incomplete file.\n");
     196           0 :         return AVERROR_INVALIDDATA;
     197             :     }
     198          30 :     bytestream2_skip(&s->gb, len_section);
     199             : 
     200             :     /* image section */
     201          30 :     if (bytestream2_get_bytes_left(&s->gb) < 2) {
     202           0 :         av_log(s->avctx, AV_LOG_ERROR, "File without image data section.\n");
     203           0 :         return AVERROR_INVALIDDATA;
     204             :     }
     205             : 
     206          30 :     s->compression = bytestream2_get_be16(&s->gb);
     207          30 :     switch (s->compression) {
     208          30 :     case 0:
     209             :     case 1:
     210          30 :         break;
     211           0 :     case 2:
     212           0 :         avpriv_request_sample(s->avctx, "ZIP without predictor compression");
     213           0 :         return AVERROR_PATCHWELCOME;
     214             :         break;
     215           0 :     case 3:
     216           0 :         avpriv_request_sample(s->avctx, "ZIP with predictor compression");
     217           0 :         return AVERROR_PATCHWELCOME;
     218             :         break;
     219           0 :     default:
     220           0 :         av_log(s->avctx, AV_LOG_ERROR, "Unknown compression %d.\n", s->compression);
     221           0 :         return AVERROR_INVALIDDATA;
     222             :     }
     223             : 
     224          30 :     return ret;
     225             : }
     226             : 
     227           8 : static int decode_rle(PSDContext * s){
     228             :     unsigned int scanline_count;
     229             :     unsigned int sl, count;
     230           8 :     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           8 :     scanline_count = s->height * s->channel_count;
     237             : 
     238             :     /* scanline table */
     239           8 :     if (bytestream2_get_bytes_left(&s->gb) < scanline_count * 2) {
     240           0 :         av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline table.\n");
     241           0 :         return AVERROR_INVALIDDATA;
     242             :     }
     243           8 :     bytestream2_skip(&s->gb, scanline_count * 2);/* size of each scanline */
     244             : 
     245             :     /* decode rle data scanline by scanline */
     246        2812 :     for (sl = 0; sl < scanline_count; sl++) {
     247        2804 :         count = 0;
     248             : 
     249       24148 :         while (count < s->line_size) {
     250       18540 :             rle_char = bytestream2_get_byte(&s->gb);
     251             : 
     252       18540 :             if (rle_char <= 0) {/* byte repeat */
     253       12340 :                 repeat_count = rle_char * -1;
     254             : 
     255       12340 :                 if (bytestream2_get_bytes_left(&s->gb) < 1) {
     256           0 :                     av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
     257           0 :                     return AVERROR_INVALIDDATA;
     258             :                 }
     259             : 
     260       12340 :                 if (target_index + repeat_count >= s->uncompressed_size) {
     261           0 :                     av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
     262           0 :                     return AVERROR_INVALIDDATA;
     263             :                 }
     264             : 
     265       12340 :                 v = bytestream2_get_byte(&s->gb);
     266      222692 :                 for (p = 0; p <= repeat_count; p++) {
     267      210352 :                     s->tmp[target_index++] = v;
     268             :                 }
     269       12340 :                 count += repeat_count + 1;
     270             :             } else {
     271        6200 :                 if (bytestream2_get_bytes_left(&s->gb) < rle_char) {
     272           0 :                     av_log(s->avctx, AV_LOG_ERROR, "Not enough data for rle scanline.\n");
     273           0 :                     return AVERROR_INVALIDDATA;
     274             :                 }
     275             : 
     276        6200 :                 if (target_index + rle_char >= s->uncompressed_size) {
     277           0 :                     av_log(s->avctx, AV_LOG_ERROR, "Invalid rle char.\n");
     278           0 :                     return AVERROR_INVALIDDATA;
     279             :                 }
     280             : 
     281      250010 :                 for (p = 0; p <= rle_char; p++) {
     282      243810 :                     v = bytestream2_get_byte(&s->gb);
     283      243810 :                     s->tmp[target_index++] = v;
     284             :                 }
     285        6200 :                 count += rle_char + 1;
     286             :             }
     287             :         }
     288             :     }
     289             : 
     290           8 :     return 0;
     291             : }
     292             : 
     293          30 : static int decode_frame(AVCodecContext *avctx, void *data,
     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          30 :     uint8_t eq_channel[4] = {2,0,1,3};/* RGBA -> GBRA channel order */
     301             :     uint8_t plane_number;
     302             : 
     303          30 :     AVFrame *picture = data;
     304             : 
     305          30 :     PSDContext *s = avctx->priv_data;
     306          30 :     s->avctx     = avctx;
     307          30 :     s->channel_count = 0;
     308          30 :     s->channel_depth = 0;
     309          30 :     s->tmp           = NULL;
     310          30 :     s->line_size     = 0;
     311             : 
     312          30 :     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
     313             : 
     314          30 :     if ((ret = decode_header(s)) < 0)
     315           0 :         return ret;
     316             : 
     317          30 :     s->pixel_size = s->channel_depth >> 3;/* in byte */
     318          30 :     s->line_size = s->width * s->pixel_size;
     319             : 
     320          30 :     switch (s->color_mode) {
     321           2 :     case PSD_BITMAP:
     322           2 :         if (s->channel_depth != 1 || s->channel_count != 1) {
     323           0 :             av_log(s->avctx, AV_LOG_ERROR,
     324             :                     "Invalid bitmap file (channel_depth %d, channel_count %d)\n",
     325           0 :                     s->channel_depth, s->channel_count);
     326           0 :             return AVERROR_INVALIDDATA;
     327             :         }
     328           2 :         s->line_size = s->width + 7 >> 3;
     329           2 :         avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
     330           2 :         break;
     331           2 :     case PSD_INDEXED:
     332           2 :         if (s->channel_depth != 8 || s->channel_count != 1) {
     333           0 :             av_log(s->avctx, AV_LOG_ERROR,
     334             :                    "Invalid indexed file (channel_depth %d, channel_count %d)\n",
     335           0 :                    s->channel_depth, s->channel_count);
     336           0 :             return AVERROR_INVALIDDATA;
     337             :         }
     338           2 :         avctx->pix_fmt = AV_PIX_FMT_PAL8;
     339           2 :         break;
     340          16 :     case PSD_RGB:
     341          16 :         if (s->channel_count == 3) {
     342          10 :             if (s->channel_depth == 8) {
     343           6 :                 avctx->pix_fmt = AV_PIX_FMT_GBRP;
     344           4 :             } else if (s->channel_depth == 16) {
     345           4 :                 avctx->pix_fmt = AV_PIX_FMT_GBRP16BE;
     346             :             } else {
     347           0 :                 avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
     348           0 :                 return AVERROR_PATCHWELCOME;
     349             :             }
     350           6 :         } else if (s->channel_count == 4) {
     351           6 :             if (s->channel_depth == 8) {
     352           4 :                 avctx->pix_fmt = AV_PIX_FMT_GBRAP;
     353           2 :             } else if (s->channel_depth == 16) {
     354           2 :                 avctx->pix_fmt = AV_PIX_FMT_GBRAP16BE;
     355             :             } else {
     356           0 :                 avpriv_report_missing_feature(avctx, "channel depth %d for rgb", s->channel_depth);
     357           0 :                 return AVERROR_PATCHWELCOME;
     358             :             }
     359             :         } else {
     360           0 :             avpriv_report_missing_feature(avctx, "channel count %d for rgb", s->channel_count);
     361           0 :             return AVERROR_PATCHWELCOME;
     362             :         }
     363          16 :         break;
     364           2 :     case PSD_DUOTONE:
     365           2 :         av_log(avctx, AV_LOG_WARNING, "ignoring unknown duotone specification.\n");
     366          10 :     case PSD_GRAYSCALE:
     367          10 :         if (s->channel_count == 1) {
     368           6 :             if (s->channel_depth == 8) {
     369           4 :                 avctx->pix_fmt = AV_PIX_FMT_GRAY8;
     370           2 :             } else if (s->channel_depth == 16) {
     371           2 :                 avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
     372             :             } else {
     373           0 :                 avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
     374           0 :                 return AVERROR_PATCHWELCOME;
     375             :             }
     376           4 :         } else if (s->channel_count == 2) {
     377           4 :             if (s->channel_depth == 8) {
     378           2 :                 avctx->pix_fmt = AV_PIX_FMT_YA8;
     379           2 :             } else if (s->channel_depth == 16) {
     380           2 :                 avctx->pix_fmt = AV_PIX_FMT_YA16BE;
     381             :             } else {
     382           0 :                 avpriv_report_missing_feature(avctx, "channel depth %d for grayscale", s->channel_depth);
     383           0 :                 return AVERROR_PATCHWELCOME;
     384             :             }
     385             :         } else {
     386           0 :             avpriv_report_missing_feature(avctx, "channel count %d for grayscale", s->channel_count);
     387           0 :             return AVERROR_PATCHWELCOME;
     388             :         }
     389          10 :         break;
     390           0 :     default:
     391           0 :         avpriv_report_missing_feature(avctx, "color mode %d", s->color_mode);
     392           0 :         return AVERROR_PATCHWELCOME;
     393             :     }
     394             : 
     395          30 :     s->uncompressed_size = s->line_size * s->height * s->channel_count;
     396             : 
     397          30 :     if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
     398           0 :         return ret;
     399             : 
     400             :     /* decode picture if need */
     401          30 :     if (s->compression == PSD_RLE) {
     402           8 :         s->tmp = av_malloc(s->uncompressed_size);
     403           8 :         if (!s->tmp)
     404           0 :             return AVERROR(ENOMEM);
     405             : 
     406           8 :         ret = decode_rle(s);
     407             : 
     408           8 :         if (ret < 0) {
     409           0 :             av_freep(&s->tmp);
     410           0 :             return ret;
     411             :         }
     412             : 
     413           8 :         ptr_data = s->tmp;
     414             :     } else {
     415          22 :         if (bytestream2_get_bytes_left(&s->gb) < s->uncompressed_size) {
     416           0 :             av_log(s->avctx, AV_LOG_ERROR, "Not enough data for raw image data section.\n");
     417           0 :             return AVERROR_INVALIDDATA;
     418             :         }
     419          22 :         ptr_data = s->gb.buffer;
     420             :     }
     421             : 
     422             :     /* Store data */
     423          34 :     if ((avctx->pix_fmt == AV_PIX_FMT_YA8)||(avctx->pix_fmt == AV_PIX_FMT_YA16BE)){/* Interleaved */
     424           4 :         ptr = picture->data[0];
     425          12 :         for (c = 0; c < s->channel_count; c++) {
     426        1032 :             for (y = 0; y < s->height; y++) {
     427      132096 :                 for (x = 0; x < s->width; x++) {
     428      131072 :                     index_out = y * picture->linesize[0] + x * s->channel_count * s->pixel_size + c * s->pixel_size;
     429      327680 :                     for (p = 0; p < s->pixel_size; p++) {
     430      196608 :                         ptr[index_out + p] = *ptr_data;
     431      196608 :                         ptr_data ++;
     432             :                     }
     433             :                 }
     434             :             }
     435             :         }
     436             :     } else {/* Planar */
     437          26 :         if (s->channel_count == 1)/* gray 8 or gray 16be */
     438          10 :             eq_channel[0] = 0;/* assign first channel, to first plane */
     439             : 
     440          90 :         for (c = 0; c < s->channel_count; c++) {
     441          64 :             plane_number = eq_channel[c];
     442          64 :             ptr = picture->data[plane_number];/* get the right plane */
     443        8238 :             for (y = 0; y < s->height; y++) {
     444        8174 :                 memcpy(ptr, ptr_data, s->line_size);
     445        8174 :                 ptr += picture->linesize[plane_number];
     446        8174 :                 ptr_data += s->line_size;
     447             :             }
     448             :         }
     449             :     }
     450             : 
     451          30 :     if (s->color_mode == PSD_INDEXED) {
     452           2 :         picture->palette_has_changed = 1;
     453           2 :         memcpy(picture->data[1], s->palette, AVPALETTE_SIZE);
     454             :     }
     455             : 
     456          30 :     av_freep(&s->tmp);
     457             : 
     458          30 :     picture->pict_type = AV_PICTURE_TYPE_I;
     459          30 :     *got_frame = 1;
     460             : 
     461          30 :     return avpkt->size;
     462             : }
     463             : 
     464             : AVCodec ff_psd_decoder = {
     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,
     471             :     .capabilities     = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     472             : };

Generated by: LCOV version 1.13