Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * DPX (.dpx) image decoder
  3.  * Copyright (c) 2009 Jimmy Christensen
  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 "libavutil/intreadwrite.h"
  23. #include "libavutil/intfloat.h"
  24. #include "libavutil/imgutils.h"
  25. #include "bytestream.h"
  26. #include "avcodec.h"
  27. #include "internal.h"
  28.  
  29. static unsigned int read16(const uint8_t **ptr, int is_big)
  30. {
  31.     unsigned int temp;
  32.     if (is_big) {
  33.         temp = AV_RB16(*ptr);
  34.     } else {
  35.         temp = AV_RL16(*ptr);
  36.     }
  37.     *ptr += 2;
  38.     return temp;
  39. }
  40.  
  41. static unsigned int read32(const uint8_t **ptr, int is_big)
  42. {
  43.     unsigned int temp;
  44.     if (is_big) {
  45.         temp = AV_RB32(*ptr);
  46.     } else {
  47.         temp = AV_RL32(*ptr);
  48.     }
  49.     *ptr += 4;
  50.     return temp;
  51. }
  52.  
  53. static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
  54.                                   int * n_datum, int is_big)
  55. {
  56.     if (*n_datum)
  57.         (*n_datum)--;
  58.     else {
  59.         *lbuf = read32(ptr, is_big);
  60.         *n_datum = 2;
  61.     }
  62.  
  63.     *lbuf = (*lbuf << 10) | (*lbuf >> 22);
  64.  
  65.     return *lbuf & 0x3FF;
  66. }
  67.  
  68. static int decode_frame(AVCodecContext *avctx,
  69.                         void *data,
  70.                         int *got_frame,
  71.                         AVPacket *avpkt)
  72. {
  73.     const uint8_t *buf = avpkt->data;
  74.     int buf_size       = avpkt->size;
  75.     AVFrame *const p = data;
  76.     uint8_t *ptr[AV_NUM_DATA_POINTERS];
  77.  
  78.     unsigned int offset;
  79.     int magic_num, endian;
  80.     int x, y, stride, i, ret;
  81.     int w, h, bits_per_color, descriptor, elements, packing;
  82.     int encoding, need_align = 0;
  83.  
  84.     unsigned int rgbBuffer = 0;
  85.     int n_datum = 0;
  86.  
  87.     if (avpkt->size <= 1634) {
  88.         av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
  89.         return AVERROR_INVALIDDATA;
  90.     }
  91.  
  92.     magic_num = AV_RB32(buf);
  93.     buf += 4;
  94.  
  95.     /* Check if the files "magic number" is "SDPX" which means it uses
  96.      * big-endian or XPDS which is for little-endian files */
  97.     if (magic_num == AV_RL32("SDPX")) {
  98.         endian = 0;
  99.     } else if (magic_num == AV_RB32("SDPX")) {
  100.         endian = 1;
  101.     } else {
  102.         av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
  103.         return AVERROR_INVALIDDATA;
  104.     }
  105.  
  106.     offset = read32(&buf, endian);
  107.     if (avpkt->size <= offset) {
  108.         av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
  109.         return AVERROR_INVALIDDATA;
  110.     }
  111.  
  112.     // Check encryption
  113.     buf = avpkt->data + 660;
  114.     ret = read32(&buf, endian);
  115.     if (ret != 0xFFFFFFFF) {
  116.         avpriv_report_missing_feature(avctx, "Encryption");
  117.         av_log(avctx, AV_LOG_WARNING, "The image is encrypted and may "
  118.                "not properly decode.\n");
  119.     }
  120.  
  121.     // Need to end in 0x304 offset from start of file
  122.     buf = avpkt->data + 0x304;
  123.     w = read32(&buf, endian);
  124.     h = read32(&buf, endian);
  125.  
  126.     if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
  127.         return ret;
  128.  
  129.     // Need to end in 0x320 to read the descriptor
  130.     buf += 20;
  131.     descriptor = buf[0];
  132.  
  133.     // Need to end in 0x323 to read the bits per color
  134.     buf += 3;
  135.     avctx->bits_per_raw_sample =
  136.     bits_per_color = buf[0];
  137.     buf++;
  138.     packing = read16(&buf, endian);
  139.     encoding = read16(&buf, endian);
  140.  
  141.     if (packing > 1) {
  142.         avpriv_report_missing_feature(avctx, "Packing %d", packing);
  143.         return AVERROR_PATCHWELCOME;
  144.     }
  145.     if (encoding) {
  146.         avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
  147.         return AVERROR_PATCHWELCOME;
  148.     }
  149.  
  150.     buf += 820;
  151.     avctx->sample_aspect_ratio.num = read32(&buf, endian);
  152.     avctx->sample_aspect_ratio.den = read32(&buf, endian);
  153.     if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
  154.         av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
  155.                    avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den,
  156.                   0x10000);
  157.     else
  158.         avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
  159.  
  160.     if (offset >= 1724 + 4) {
  161.         buf = avpkt->data + 1724;
  162.         i = read32(&buf, endian);
  163.         if(i) {
  164.             AVRational q = av_d2q(av_int2float(i), 4096);
  165.             if (q.num > 0 && q.den > 0)
  166.                 avctx->framerate = q;
  167.         }
  168.     }
  169.  
  170.     switch (descriptor) {
  171.     case 6:  // Y
  172.         elements = 1;
  173.         break;
  174.     case 52: // ABGR
  175.     case 51: // RGBA
  176.     case 103: // UYVA4444
  177.         elements = 4;
  178.         break;
  179.     case 50: // RGB
  180.     case 102: // UYV444
  181.         elements = 3;
  182.         break;
  183.     case 100: // UYVY422
  184.         elements = 2;
  185.         break;
  186.     default:
  187.         avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor);
  188.         return AVERROR_PATCHWELCOME;
  189.     }
  190.  
  191.     switch (bits_per_color) {
  192.     case 8:
  193.         stride = avctx->width * elements;
  194.         break;
  195.     case 10:
  196.         if (!packing) {
  197.             av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
  198.             return -1;
  199.         }
  200.         stride = (avctx->width * elements + 2) / 3 * 4;
  201.         break;
  202.     case 12:
  203.         if (!packing) {
  204.             av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
  205.             return -1;
  206.         }
  207.         stride = 2 * avctx->width * elements;
  208.         break;
  209.     case 16:
  210.         stride = 2 * avctx->width * elements;
  211.         break;
  212.     case 1:
  213.     case 32:
  214.     case 64:
  215.         avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color);
  216.         return AVERROR_PATCHWELCOME;
  217.     default:
  218.         return AVERROR_INVALIDDATA;
  219.     }
  220.  
  221.     // Table 3c: Runs will always break at scan line boundaries. Packing
  222.     // will always break to the next 32-bit word at scan-line boundaries.
  223.     // Unfortunately, the encoder produced invalid files, so attempt
  224.     // to detect it
  225.     need_align = FFALIGN(stride, 4);
  226.     if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
  227.         // Alignment seems unappliable, try without
  228.         if (stride*avctx->height + (int64_t)offset > avpkt->size) {
  229.             av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
  230.             return AVERROR_INVALIDDATA;
  231.         } else {
  232.             av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
  233.                    "alignment.\n");
  234.             need_align = 0;
  235.         }
  236.     } else {
  237.         need_align -= stride;
  238.         stride = FFALIGN(stride, 4);
  239.     }
  240.  
  241.     switch (1000 * descriptor + 10 * bits_per_color + endian) {
  242.     case 6081:
  243.     case 6080:
  244.         avctx->pix_fmt = AV_PIX_FMT_GRAY8;
  245.         break;
  246.     case 50081:
  247.     case 50080:
  248.         avctx->pix_fmt = AV_PIX_FMT_RGB24;
  249.         break;
  250.     case 52081:
  251.     case 52080:
  252.         avctx->pix_fmt = AV_PIX_FMT_ABGR;
  253.         break;
  254.     case 51081:
  255.     case 51080:
  256.         avctx->pix_fmt = AV_PIX_FMT_RGBA;
  257.         break;
  258.     case 50100:
  259.     case 51100:
  260.     case 50101:
  261.     case 51101:
  262.         avctx->pix_fmt = AV_PIX_FMT_GBRP10;
  263.         break;
  264.     case 50120:
  265.     case 51120:
  266.     case 50121:
  267.     case 51121:
  268.         avctx->pix_fmt = AV_PIX_FMT_GBRP12;
  269.         break;
  270.     case 6161:
  271.         avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
  272.         break;
  273.     case 6160:
  274.         avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
  275.         break;
  276.     case 50161:
  277.         avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
  278.         break;
  279.     case 50160:
  280.         avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
  281.         break;
  282.     case 51161:
  283.         avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
  284.         break;
  285.     case 51160:
  286.         avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
  287.         break;
  288.     case 100081:
  289.         avctx->pix_fmt = AV_PIX_FMT_UYVY422;
  290.         break;
  291.     case 102081:
  292.         avctx->pix_fmt = AV_PIX_FMT_YUV444P;
  293.         break;
  294.     case 103081:
  295.         avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
  296.         break;
  297.     default:
  298.         av_log(avctx, AV_LOG_ERROR, "Unsupported format\n");
  299.         return AVERROR_PATCHWELCOME;
  300.     }
  301.  
  302.     ff_set_sar(avctx, avctx->sample_aspect_ratio);
  303.  
  304.     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
  305.         return ret;
  306.  
  307.     // Move pointer to offset from start of file
  308.     buf =  avpkt->data + offset;
  309.  
  310.     for (i=0; i<AV_NUM_DATA_POINTERS; i++)
  311.         ptr[i] = p->data[i];
  312.  
  313.     switch (bits_per_color) {
  314.     case 10:
  315.         for (x = 0; x < avctx->height; x++) {
  316.             uint16_t *dst[3] = {(uint16_t*)ptr[0],
  317.                                 (uint16_t*)ptr[1],
  318.                                 (uint16_t*)ptr[2]};
  319.             for (y = 0; y < avctx->width; y++) {
  320.                 *dst[2]++ = read10in32(&buf, &rgbBuffer,
  321.                                        &n_datum, endian);
  322.                 *dst[0]++ = read10in32(&buf, &rgbBuffer,
  323.                                        &n_datum, endian);
  324.                 *dst[1]++ = read10in32(&buf, &rgbBuffer,
  325.                                        &n_datum, endian);
  326.                 // For 10 bit, ignore alpha
  327.                 if (elements == 4)
  328.                     read10in32(&buf, &rgbBuffer,
  329.                                &n_datum, endian);
  330.             }
  331.             n_datum = 0;
  332.             for (i = 0; i < 3; i++)
  333.                 ptr[i] += p->linesize[i];
  334.         }
  335.         break;
  336.     case 12:
  337.         for (x = 0; x < avctx->height; x++) {
  338.             uint16_t *dst[3] = {(uint16_t*)ptr[0],
  339.                                 (uint16_t*)ptr[1],
  340.                                 (uint16_t*)ptr[2]};
  341.             for (y = 0; y < avctx->width; y++) {
  342.                 *dst[2] = read16(&buf, endian) >> 4;
  343.                 dst[2]++;
  344.                 *dst[0] = read16(&buf, endian) >> 4;
  345.                 dst[0]++;
  346.                 *dst[1] = read16(&buf, endian) >> 4;
  347.                 dst[1]++;
  348.                 // For 12 bit, ignore alpha
  349.                 if (elements == 4)
  350.                     buf += 2;
  351.             }
  352.             for (i = 0; i < 3; i++)
  353.                 ptr[i] += p->linesize[i];
  354.             // Jump to next aligned position
  355.             buf += need_align;
  356.         }
  357.         break;
  358.     case 16:
  359.         elements *= 2;
  360.     case 8:
  361.         if (   avctx->pix_fmt == AV_PIX_FMT_YUVA444P
  362.             || avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
  363.             for (x = 0; x < avctx->height; x++) {
  364.                 ptr[0] = p->data[0] + x * p->linesize[0];
  365.                 ptr[1] = p->data[1] + x * p->linesize[1];
  366.                 ptr[2] = p->data[2] + x * p->linesize[2];
  367.                 ptr[3] = p->data[3] + x * p->linesize[3];
  368.                 for (y = 0; y < avctx->width; y++) {
  369.                     *ptr[1]++ = *buf++;
  370.                     *ptr[0]++ = *buf++;
  371.                     *ptr[2]++ = *buf++;
  372.                     if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P)
  373.                         *ptr[3]++ = *buf++;
  374.                 }
  375.             }
  376.         } else {
  377.         av_image_copy_plane(ptr[0], p->linesize[0],
  378.                             buf, stride,
  379.                             elements * avctx->width, avctx->height);
  380.         }
  381.         break;
  382.     }
  383.  
  384.     *got_frame = 1;
  385.  
  386.     return buf_size;
  387. }
  388.  
  389. AVCodec ff_dpx_decoder = {
  390.     .name           = "dpx",
  391.     .long_name      = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
  392.     .type           = AVMEDIA_TYPE_VIDEO,
  393.     .id             = AV_CODEC_ID_DPX,
  394.     .decode         = decode_frame,
  395.     .capabilities   = AV_CODEC_CAP_DR1,
  396. };
  397.