Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Quicktime Animation (RLE) Video Decoder
  3.  * Copyright (C) 2004 the ffmpeg project
  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. /**
  23.  * @file
  24.  * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
  25.  * For more information about the QT RLE format, visit:
  26.  *   http://www.pcisys.net/~melanson/codecs/
  27.  *
  28.  * The QT RLE decoder has seven modes of operation:
  29.  * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
  30.  * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
  31.  * data. 24-bit data is RGB24 and 32-bit data is RGB32.
  32.  */
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37.  
  38. #include "avcodec.h"
  39. #include "bytestream.h"
  40. #include "internal.h"
  41.  
  42. typedef struct QtrleContext {
  43.     AVCodecContext *avctx;
  44.     AVFrame *frame;
  45.  
  46.     GetByteContext g;
  47.     uint32_t pal[256];
  48. } QtrleContext;
  49.  
  50. #define CHECK_PIXEL_PTR(n)                                                            \
  51.     if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) {                       \
  52.         av_log (s->avctx, AV_LOG_ERROR, "Problem: pixel_ptr = %d, pixel_limit = %d\n",\
  53.                 pixel_ptr + n, pixel_limit);                                          \
  54.         return;                                                                       \
  55.     }                                                                                 \
  56.  
  57. static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change)
  58. {
  59.     int rle_code;
  60.     int pixel_ptr;
  61.     int row_inc = s->frame->linesize[0];
  62.     uint8_t pi0, pi1;  /* 2 8-pixel values */
  63.     uint8_t *rgb = s->frame->data[0];
  64.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  65.     int skip;
  66.     /* skip & 0x80 appears to mean 'start a new line', which can be interpreted
  67.      * as 'go to next line' during the decoding of a frame but is 'go to first
  68.      * line' at the beginning. Since we always interpret it as 'go to next line'
  69.      * in the decoding loop (which makes code simpler/faster), the first line
  70.      * would not be counted, so we count one more.
  71.      * See: https://trac.ffmpeg.org/ticket/226
  72.      * In the following decoding loop, row_ptr will be the position of the
  73.      * current row. */
  74.  
  75.     row_ptr  -= row_inc;
  76.     pixel_ptr = row_ptr;
  77.     lines_to_change++;
  78.     while (lines_to_change) {
  79.         skip     =              bytestream2_get_byte(&s->g);
  80.         rle_code = (int8_t)bytestream2_get_byte(&s->g);
  81.         if (rle_code == 0)
  82.             break;
  83.         if(skip & 0x80) {
  84.             lines_to_change--;
  85.             row_ptr += row_inc;
  86.             pixel_ptr = row_ptr + 2 * (skip & 0x7f);
  87.         } else
  88.             pixel_ptr += 2 * skip;
  89.         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  90.  
  91.         if(rle_code == -1)
  92.             continue;
  93.  
  94.         if (rle_code < 0) {
  95.             /* decode the run length code */
  96.             rle_code = -rle_code;
  97.             /* get the next 2 bytes from the stream, treat them as groups
  98.              * of 8 pixels, and output them rle_code times */
  99.  
  100.             pi0 = bytestream2_get_byte(&s->g);
  101.             pi1 = bytestream2_get_byte(&s->g);
  102.             CHECK_PIXEL_PTR(rle_code * 2);
  103.  
  104.             while (rle_code--) {
  105.                 rgb[pixel_ptr++] = pi0;
  106.                 rgb[pixel_ptr++] = pi1;
  107.             }
  108.         } else {
  109.             /* copy the same pixel directly to output 2 times */
  110.             rle_code *= 2;
  111.             CHECK_PIXEL_PTR(rle_code);
  112.  
  113.             bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code);
  114.             pixel_ptr += rle_code;
  115.         }
  116.     }
  117. }
  118.  
  119. static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr,
  120.                                        int lines_to_change, int bpp)
  121. {
  122.     int rle_code, i;
  123.     int pixel_ptr;
  124.     int row_inc = s->frame->linesize[0];
  125.     uint8_t pi[16];  /* 16 palette indices */
  126.     uint8_t *rgb = s->frame->data[0];
  127.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  128.     int num_pixels = (bpp == 4) ? 8 : 16;
  129.  
  130.     while (lines_to_change--) {
  131.         pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1));
  132.         CHECK_PIXEL_PTR(0);
  133.  
  134.         while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
  135.             if (rle_code == 0) {
  136.                 /* there's another skip code in the stream */
  137.                 pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 1));
  138.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  139.             } else if (rle_code < 0) {
  140.                 /* decode the run length code */
  141.                 rle_code = -rle_code;
  142.                 /* get the next 4 bytes from the stream, treat them as palette
  143.                  * indexes, and output them rle_code times */
  144.                 for (i = num_pixels-1; i >= 0; i--) {
  145.                     pi[num_pixels-1-i] = (bytestream2_peek_byte(&s->g) >> ((i*bpp) & 0x07)) & ((1<<bpp)-1);
  146.                     bytestream2_skip(&s->g, ((i & ((num_pixels>>2)-1)) == 0));
  147.                 }
  148.                 CHECK_PIXEL_PTR(rle_code * num_pixels);
  149.                 while (rle_code--) {
  150.                     memcpy(&rgb[pixel_ptr], &pi, num_pixels);
  151.                     pixel_ptr += num_pixels;
  152.                 }
  153.             } else {
  154.                 /* copy the same pixel directly to output 4 times */
  155.                 rle_code *= 4;
  156.                 CHECK_PIXEL_PTR(rle_code*(num_pixels>>2));
  157.                 while (rle_code--) {
  158.                     if(bpp == 4) {
  159.                         int x = bytestream2_get_byte(&s->g);
  160.                         rgb[pixel_ptr++] = (x >> 4) & 0x0f;
  161.                         rgb[pixel_ptr++] =  x       & 0x0f;
  162.                     } else {
  163.                         int x = bytestream2_get_byte(&s->g);
  164.                         rgb[pixel_ptr++] = (x >> 6) & 0x03;
  165.                         rgb[pixel_ptr++] = (x >> 4) & 0x03;
  166.                         rgb[pixel_ptr++] = (x >> 2) & 0x03;
  167.                         rgb[pixel_ptr++] =  x       & 0x03;
  168.                     }
  169.                 }
  170.             }
  171.         }
  172.         row_ptr += row_inc;
  173.     }
  174. }
  175.  
  176. static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change)
  177. {
  178.     int rle_code;
  179.     int pixel_ptr;
  180.     int row_inc = s->frame->linesize[0];
  181.     uint8_t pi1, pi2, pi3, pi4;  /* 4 palette indexes */
  182.     uint8_t *rgb = s->frame->data[0];
  183.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  184.  
  185.     while (lines_to_change--) {
  186.         pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1));
  187.         CHECK_PIXEL_PTR(0);
  188.  
  189.         while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
  190.             if (rle_code == 0) {
  191.                 /* there's another skip code in the stream */
  192.                 pixel_ptr += (4 * (bytestream2_get_byte(&s->g) - 1));
  193.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  194.             } else if (rle_code < 0) {
  195.                 /* decode the run length code */
  196.                 rle_code = -rle_code;
  197.                 /* get the next 4 bytes from the stream, treat them as palette
  198.                  * indexes, and output them rle_code times */
  199.                 pi1 = bytestream2_get_byte(&s->g);
  200.                 pi2 = bytestream2_get_byte(&s->g);
  201.                 pi3 = bytestream2_get_byte(&s->g);
  202.                 pi4 = bytestream2_get_byte(&s->g);
  203.  
  204.                 CHECK_PIXEL_PTR(rle_code * 4);
  205.  
  206.                 while (rle_code--) {
  207.                     rgb[pixel_ptr++] = pi1;
  208.                     rgb[pixel_ptr++] = pi2;
  209.                     rgb[pixel_ptr++] = pi3;
  210.                     rgb[pixel_ptr++] = pi4;
  211.                 }
  212.             } else {
  213.                 /* copy the same pixel directly to output 4 times */
  214.                 rle_code *= 4;
  215.                 CHECK_PIXEL_PTR(rle_code);
  216.  
  217.                 bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code);
  218.                 pixel_ptr += rle_code;
  219.             }
  220.         }
  221.         row_ptr += row_inc;
  222.     }
  223. }
  224.  
  225. static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change)
  226. {
  227.     int rle_code;
  228.     int pixel_ptr;
  229.     int row_inc = s->frame->linesize[0];
  230.     uint16_t rgb16;
  231.     uint8_t *rgb = s->frame->data[0];
  232.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  233.  
  234.     while (lines_to_change--) {
  235.         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2;
  236.         CHECK_PIXEL_PTR(0);
  237.  
  238.         while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
  239.             if (rle_code == 0) {
  240.                 /* there's another skip code in the stream */
  241.                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 2;
  242.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  243.             } else if (rle_code < 0) {
  244.                 /* decode the run length code */
  245.                 rle_code = -rle_code;
  246.                 rgb16 = bytestream2_get_be16(&s->g);
  247.  
  248.                 CHECK_PIXEL_PTR(rle_code * 2);
  249.  
  250.                 while (rle_code--) {
  251.                     *(uint16_t *)(&rgb[pixel_ptr]) = rgb16;
  252.                     pixel_ptr += 2;
  253.                 }
  254.             } else {
  255.                 CHECK_PIXEL_PTR(rle_code * 2);
  256.  
  257.                 /* copy pixels directly to output */
  258.                 while (rle_code--) {
  259.                     rgb16 = bytestream2_get_be16(&s->g);
  260.                     *(uint16_t *)(&rgb[pixel_ptr]) = rgb16;
  261.                     pixel_ptr += 2;
  262.                 }
  263.             }
  264.         }
  265.         row_ptr += row_inc;
  266.     }
  267. }
  268.  
  269. static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change)
  270. {
  271.     int rle_code;
  272.     int pixel_ptr;
  273.     int row_inc = s->frame->linesize[0];
  274.     uint8_t r, g, b;
  275.     uint8_t *rgb = s->frame->data[0];
  276.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  277.  
  278.     while (lines_to_change--) {
  279.         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3;
  280.         CHECK_PIXEL_PTR(0);
  281.  
  282.         while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
  283.             if (rle_code == 0) {
  284.                 /* there's another skip code in the stream */
  285.                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 3;
  286.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  287.             } else if (rle_code < 0) {
  288.                 /* decode the run length code */
  289.                 rle_code = -rle_code;
  290.                 r = bytestream2_get_byte(&s->g);
  291.                 g = bytestream2_get_byte(&s->g);
  292.                 b = bytestream2_get_byte(&s->g);
  293.  
  294.                 CHECK_PIXEL_PTR(rle_code * 3);
  295.  
  296.                 while (rle_code--) {
  297.                     rgb[pixel_ptr++] = r;
  298.                     rgb[pixel_ptr++] = g;
  299.                     rgb[pixel_ptr++] = b;
  300.                 }
  301.             } else {
  302.                 CHECK_PIXEL_PTR(rle_code * 3);
  303.  
  304.                 /* copy pixels directly to output */
  305.                 while (rle_code--) {
  306.                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
  307.                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
  308.                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
  309.                 }
  310.             }
  311.         }
  312.         row_ptr += row_inc;
  313.     }
  314. }
  315.  
  316. static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change)
  317. {
  318.     int rle_code;
  319.     int pixel_ptr;
  320.     int row_inc = s->frame->linesize[0];
  321.     unsigned int argb;
  322.     uint8_t *rgb = s->frame->data[0];
  323.     int pixel_limit = s->frame->linesize[0] * s->avctx->height;
  324.  
  325.     while (lines_to_change--) {
  326.         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4;
  327.         CHECK_PIXEL_PTR(0);
  328.  
  329.         while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) {
  330.             if (rle_code == 0) {
  331.                 /* there's another skip code in the stream */
  332.                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 4;
  333.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  334.             } else if (rle_code < 0) {
  335.                 /* decode the run length code */
  336.                 rle_code = -rle_code;
  337.                 argb = bytestream2_get_be32(&s->g);
  338.  
  339.                 CHECK_PIXEL_PTR(rle_code * 4);
  340.  
  341.                 while (rle_code--) {
  342.                     AV_WN32A(rgb + pixel_ptr, argb);
  343.                     pixel_ptr += 4;
  344.                 }
  345.             } else {
  346.                 CHECK_PIXEL_PTR(rle_code * 4);
  347.  
  348.                 /* copy pixels directly to output */
  349.                 while (rle_code--) {
  350.                     argb = bytestream2_get_be32(&s->g);
  351.                     AV_WN32A(rgb + pixel_ptr, argb);
  352.                     pixel_ptr  += 4;
  353.                 }
  354.             }
  355.         }
  356.         row_ptr += row_inc;
  357.     }
  358. }
  359.  
  360. static av_cold int qtrle_decode_init(AVCodecContext *avctx)
  361. {
  362.     QtrleContext *s = avctx->priv_data;
  363.  
  364.     s->avctx = avctx;
  365.     switch (avctx->bits_per_coded_sample) {
  366.     case 1:
  367.     case 33:
  368.         avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
  369.         break;
  370.  
  371.     case 2:
  372.     case 4:
  373.     case 8:
  374.     case 34:
  375.     case 36:
  376.     case 40:
  377.         avctx->pix_fmt = AV_PIX_FMT_PAL8;
  378.         break;
  379.  
  380.     case 16:
  381.         avctx->pix_fmt = AV_PIX_FMT_RGB555;
  382.         break;
  383.  
  384.     case 24:
  385.         avctx->pix_fmt = AV_PIX_FMT_RGB24;
  386.         break;
  387.  
  388.     case 32:
  389.         avctx->pix_fmt = AV_PIX_FMT_RGB32;
  390.         break;
  391.  
  392.     default:
  393.         av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  394.             avctx->bits_per_coded_sample);
  395.         return AVERROR_INVALIDDATA;
  396.     }
  397.  
  398.     s->frame = av_frame_alloc();
  399.     if (!s->frame)
  400.         return AVERROR(ENOMEM);
  401.  
  402.     return 0;
  403. }
  404.  
  405. static int qtrle_decode_frame(AVCodecContext *avctx,
  406.                               void *data, int *got_frame,
  407.                               AVPacket *avpkt)
  408. {
  409.     QtrleContext *s = avctx->priv_data;
  410.     int header, start_line;
  411.     int height, row_ptr;
  412.     int has_palette = 0;
  413.     int ret;
  414.  
  415.     bytestream2_init(&s->g, avpkt->data, avpkt->size);
  416.     if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
  417.         return ret;
  418.  
  419.     /* check if this frame is even supposed to change */
  420.     if (avpkt->size < 8)
  421.         goto done;
  422.  
  423.     /* start after the chunk size */
  424.     bytestream2_seek(&s->g, 4, SEEK_SET);
  425.  
  426.     /* fetch the header */
  427.     header = bytestream2_get_be16(&s->g);
  428.  
  429.     /* if a header is present, fetch additional decoding parameters */
  430.     if (header & 0x0008) {
  431.         if (avpkt->size < 14)
  432.             goto done;
  433.         start_line = bytestream2_get_be16(&s->g);
  434.         bytestream2_skip(&s->g, 2);
  435.         height     = bytestream2_get_be16(&s->g);
  436.         bytestream2_skip(&s->g, 2);
  437.         if (height > s->avctx->height - start_line)
  438.             goto done;
  439.     } else {
  440.         start_line = 0;
  441.         height     = s->avctx->height;
  442.     }
  443.     row_ptr = s->frame->linesize[0] * start_line;
  444.  
  445.     switch (avctx->bits_per_coded_sample) {
  446.     case 1:
  447.     case 33:
  448.         qtrle_decode_1bpp(s, row_ptr, height);
  449.         break;
  450.  
  451.     case 2:
  452.     case 34:
  453.         qtrle_decode_2n4bpp(s, row_ptr, height, 2);
  454.         has_palette = 1;
  455.         break;
  456.  
  457.     case 4:
  458.     case 36:
  459.         qtrle_decode_2n4bpp(s, row_ptr, height, 4);
  460.         has_palette = 1;
  461.         break;
  462.  
  463.     case 8:
  464.     case 40:
  465.         qtrle_decode_8bpp(s, row_ptr, height);
  466.         has_palette = 1;
  467.         break;
  468.  
  469.     case 16:
  470.         qtrle_decode_16bpp(s, row_ptr, height);
  471.         break;
  472.  
  473.     case 24:
  474.         qtrle_decode_24bpp(s, row_ptr, height);
  475.         break;
  476.  
  477.     case 32:
  478.         qtrle_decode_32bpp(s, row_ptr, height);
  479.         break;
  480.  
  481.     default:
  482.         av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  483.             avctx->bits_per_coded_sample);
  484.         break;
  485.     }
  486.  
  487.     if(has_palette) {
  488.         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
  489.  
  490.         if (pal) {
  491.             s->frame->palette_has_changed = 1;
  492.             memcpy(s->pal, pal, AVPALETTE_SIZE);
  493.         }
  494.  
  495.         /* make the palette available on the way out */
  496.         memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
  497.     }
  498.  
  499. done:
  500.     if ((ret = av_frame_ref(data, s->frame)) < 0)
  501.         return ret;
  502.     *got_frame      = 1;
  503.  
  504.     /* always report that the buffer was completely consumed */
  505.     return avpkt->size;
  506. }
  507.  
  508. static av_cold int qtrle_decode_end(AVCodecContext *avctx)
  509. {
  510.     QtrleContext *s = avctx->priv_data;
  511.  
  512.     av_frame_free(&s->frame);
  513.  
  514.     return 0;
  515. }
  516.  
  517. AVCodec ff_qtrle_decoder = {
  518.     .name           = "qtrle",
  519.     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
  520.     .type           = AVMEDIA_TYPE_VIDEO,
  521.     .id             = AV_CODEC_ID_QTRLE,
  522.     .priv_data_size = sizeof(QtrleContext),
  523.     .init           = qtrle_decode_init,
  524.     .close          = qtrle_decode_end,
  525.     .decode         = qtrle_decode_frame,
  526.     .capabilities   = CODEC_CAP_DR1,
  527. };
  528.