qtrle.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:18k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Quicktime Animation (RLE) Video Decoder
  3.  * Copyright (C) 2004 the ffmpeg project
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  */
  20. /**
  21.  * @file qtrle.c
  22.  * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
  23.  * For more information about the QT RLE format, visit:
  24.  *   http://www.pcisys.net/~melanson/codecs/
  25.  *
  26.  * The QT RLE decoder has seven modes of operation:
  27.  * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
  28.  * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
  29.  * data. 24-bit data is RGB24 and 32-bit data is RGBA32.
  30.  */
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <unistd.h>
  35. #include "common.h"
  36. #include "avcodec.h"
  37. #include "dsputil.h"
  38. typedef struct QtrleContext {
  39.     AVCodecContext *avctx;
  40.     DSPContext dsp;
  41.     AVFrame frame;
  42.     unsigned char *buf;
  43.     int size;
  44. } QtrleContext;
  45. #define CHECK_STREAM_PTR(n) 
  46.   if ((stream_ptr + n) > s->size) { 
  47.     av_log (s->avctx, AV_LOG_INFO, "Problem: stream_ptr out of bounds (%d >= %d)n", 
  48.       stream_ptr + n, s->size); 
  49.     return; 
  50.   }
  51. #define CHECK_PIXEL_PTR(n) 
  52.   if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { 
  53.     av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %dn", 
  54.       pixel_ptr + n, pixel_limit); 
  55.     return; 
  56.   } 
  57. static void qtrle_decode_1bpp(QtrleContext *s)
  58. {
  59. }
  60. static void qtrle_decode_2bpp(QtrleContext *s)
  61. {
  62. }
  63. static void qtrle_decode_4bpp(QtrleContext *s)
  64. {
  65.     int stream_ptr;
  66.     int header;
  67.     int start_line;
  68.     int lines_to_change;
  69.     int rle_code;
  70.     int row_ptr, pixel_ptr;
  71.     int row_inc = s->frame.linesize[0];
  72.     unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8;  /* 8 palette indices */
  73.     unsigned char *rgb = s->frame.data[0];
  74.     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  75.     /* check if this frame is even supposed to change */
  76.     if (s->size < 8)
  77.         return;
  78.     /* start after the chunk size */
  79.     stream_ptr = 4;
  80.     /* fetch the header */
  81.     CHECK_STREAM_PTR(2);
  82.     header = BE_16(&s->buf[stream_ptr]);
  83.     stream_ptr += 2;
  84.     /* if a header is present, fetch additional decoding parameters */
  85.     if (header & 0x0008) {
  86.         CHECK_STREAM_PTR(8);
  87.         start_line = BE_16(&s->buf[stream_ptr]);
  88.         stream_ptr += 4;
  89.         lines_to_change = BE_16(&s->buf[stream_ptr]);
  90.         stream_ptr += 4;
  91.     } else {
  92.         start_line = 0;
  93.         lines_to_change = s->avctx->height;
  94.     }
  95.     row_ptr = row_inc * start_line;
  96.     while (lines_to_change--) {
  97.         CHECK_STREAM_PTR(2);
  98.         pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1));
  99.         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  100.             if (rle_code == 0) {
  101.                 /* there's another skip code in the stream */
  102.                 CHECK_STREAM_PTR(1);
  103.                 pixel_ptr += (8 * (s->buf[stream_ptr++] - 1));
  104.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  105.             } else if (rle_code < 0) {
  106.                 /* decode the run length code */
  107.                 rle_code = -rle_code;
  108.                 /* get the next 4 bytes from the stream, treat them as palette
  109.                  * indices, and output them rle_code times */
  110.                 CHECK_STREAM_PTR(4);
  111.                 pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  112.                 pi2 = (s->buf[stream_ptr++]) & 0x0f;
  113.                 pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  114.                 pi4 = (s->buf[stream_ptr++]) & 0x0f;
  115.                 pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  116.                 pi6 = (s->buf[stream_ptr++]) & 0x0f;
  117.                 pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  118.                 pi8 = (s->buf[stream_ptr++]) & 0x0f;
  119.                 CHECK_PIXEL_PTR(rle_code * 8);
  120.                 while (rle_code--) {
  121.                     rgb[pixel_ptr++] = pi1;
  122.                     rgb[pixel_ptr++] = pi2;
  123.                     rgb[pixel_ptr++] = pi3;
  124.                     rgb[pixel_ptr++] = pi4;
  125.                     rgb[pixel_ptr++] = pi5;
  126.                     rgb[pixel_ptr++] = pi6;
  127.                     rgb[pixel_ptr++] = pi7;
  128.                     rgb[pixel_ptr++] = pi8;
  129.                 }
  130.             } else {
  131.                 /* copy the same pixel directly to output 4 times */
  132.                 rle_code *= 4;
  133.                 CHECK_STREAM_PTR(rle_code);
  134.                 CHECK_PIXEL_PTR(rle_code*2);
  135.                 while (rle_code--) {
  136.                     rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  137.                     rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
  138.                 }
  139.             }
  140.         }
  141.         row_ptr += row_inc;
  142.     }
  143. }
  144. static void qtrle_decode_8bpp(QtrleContext *s)
  145. {
  146.     int stream_ptr;
  147.     int header;
  148.     int start_line;
  149.     int lines_to_change;
  150.     int rle_code;
  151.     int row_ptr, pixel_ptr;
  152.     int row_inc = s->frame.linesize[0];
  153.     unsigned char pi1, pi2, pi3, pi4;  /* 4 palette indices */
  154.     unsigned char *rgb = s->frame.data[0];
  155.     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  156.     /* check if this frame is even supposed to change */
  157.     if (s->size < 8)
  158.         return;
  159.     /* start after the chunk size */
  160.     stream_ptr = 4;
  161.     /* fetch the header */
  162.     CHECK_STREAM_PTR(2);
  163.     header = BE_16(&s->buf[stream_ptr]);
  164.     stream_ptr += 2;
  165.     /* if a header is present, fetch additional decoding parameters */
  166.     if (header & 0x0008) {
  167.         CHECK_STREAM_PTR(8);
  168.         start_line = BE_16(&s->buf[stream_ptr]);
  169.         stream_ptr += 4;
  170.         lines_to_change = BE_16(&s->buf[stream_ptr]);
  171.         stream_ptr += 4;
  172.     } else {
  173.         start_line = 0;
  174.         lines_to_change = s->avctx->height;
  175.     }
  176.     row_ptr = row_inc * start_line;
  177.     while (lines_to_change--) {
  178.         CHECK_STREAM_PTR(2);
  179.         pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1));
  180.         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  181.             if (rle_code == 0) {
  182.                 /* there's another skip code in the stream */
  183.                 CHECK_STREAM_PTR(1);
  184.                 pixel_ptr += (4 * (s->buf[stream_ptr++] - 1));
  185.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  186.             } else if (rle_code < 0) {
  187.                 /* decode the run length code */
  188.                 rle_code = -rle_code;
  189.                 /* get the next 4 bytes from the stream, treat them as palette
  190.                  * indices, and output them rle_code times */
  191.                 CHECK_STREAM_PTR(4);
  192.                 pi1 = s->buf[stream_ptr++];
  193.                 pi2 = s->buf[stream_ptr++];
  194.                 pi3 = s->buf[stream_ptr++];
  195.                 pi4 = s->buf[stream_ptr++];
  196.                 CHECK_PIXEL_PTR(rle_code * 4);
  197.                 while (rle_code--) {
  198.                     rgb[pixel_ptr++] = pi1;
  199.                     rgb[pixel_ptr++] = pi2;
  200.                     rgb[pixel_ptr++] = pi3;
  201.                     rgb[pixel_ptr++] = pi4;
  202.                 }
  203.             } else {
  204.                 /* copy the same pixel directly to output 4 times */
  205.                 rle_code *= 4;
  206.                 CHECK_STREAM_PTR(rle_code);
  207.                 CHECK_PIXEL_PTR(rle_code);
  208.                 while (rle_code--) {
  209.                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
  210.                 }
  211.             }
  212.         }
  213.         row_ptr += row_inc;
  214.     }
  215. }
  216. static void qtrle_decode_16bpp(QtrleContext *s)
  217. {
  218.     int stream_ptr;
  219.     int header;
  220.     int start_line;
  221.     int lines_to_change;
  222.     signed char rle_code;
  223.     int row_ptr, pixel_ptr;
  224.     int row_inc = s->frame.linesize[0];
  225.     unsigned short rgb16;
  226.     unsigned char *rgb = s->frame.data[0];
  227.     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  228.     /* check if this frame is even supposed to change */
  229.     if (s->size < 8)
  230.         return;
  231.     /* start after the chunk size */
  232.     stream_ptr = 4;
  233.     /* fetch the header */
  234.     CHECK_STREAM_PTR(2);
  235.     header = BE_16(&s->buf[stream_ptr]);
  236.     stream_ptr += 2;
  237.     /* if a header is present, fetch additional decoding parameters */
  238.     if (header & 0x0008) {
  239.         CHECK_STREAM_PTR(8);
  240.         start_line = BE_16(&s->buf[stream_ptr]);
  241.         stream_ptr += 4;
  242.         lines_to_change = BE_16(&s->buf[stream_ptr]);
  243.         stream_ptr += 4;
  244.     } else {
  245.         start_line = 0;
  246.         lines_to_change = s->avctx->height;
  247.     }
  248.     row_ptr = row_inc * start_line;
  249.     while (lines_to_change--) {
  250.         CHECK_STREAM_PTR(2);
  251.         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2;
  252.         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  253.             if (rle_code == 0) {
  254.                 /* there's another skip code in the stream */
  255.                 CHECK_STREAM_PTR(1);
  256.                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 2;
  257.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  258.             } else if (rle_code < 0) {
  259.                 /* decode the run length code */
  260.                 rle_code = -rle_code;
  261.                 CHECK_STREAM_PTR(2);
  262.                 rgb16 = BE_16(&s->buf[stream_ptr]);
  263.                 stream_ptr += 2;
  264.                 CHECK_PIXEL_PTR(rle_code * 2);
  265.                 while (rle_code--) {
  266.                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  267.                     pixel_ptr += 2;
  268.                 }
  269.             } else {
  270.                 CHECK_STREAM_PTR(rle_code * 2);
  271.                 CHECK_PIXEL_PTR(rle_code * 2);
  272.                 /* copy pixels directly to output */
  273.                 while (rle_code--) {
  274.                     rgb16 = BE_16(&s->buf[stream_ptr]);
  275.                     stream_ptr += 2;
  276.                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  277.                     pixel_ptr += 2;
  278.                 }
  279.             }
  280.         }
  281.         row_ptr += row_inc;
  282.     }
  283. }
  284. static void qtrle_decode_24bpp(QtrleContext *s)
  285. {
  286.     int stream_ptr;
  287.     int header;
  288.     int start_line;
  289.     int lines_to_change;
  290.     signed char rle_code;
  291.     int row_ptr, pixel_ptr;
  292.     int row_inc = s->frame.linesize[0];
  293.     unsigned char r, g, b;
  294.     unsigned char *rgb = s->frame.data[0];
  295.     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  296.     /* check if this frame is even supposed to change */
  297.     if (s->size < 8)
  298.         return;
  299.     /* start after the chunk size */
  300.     stream_ptr = 4;
  301.     /* fetch the header */
  302.     CHECK_STREAM_PTR(2);
  303.     header = BE_16(&s->buf[stream_ptr]);
  304.     stream_ptr += 2;
  305.     /* if a header is present, fetch additional decoding parameters */
  306.     if (header & 0x0008) {
  307.         CHECK_STREAM_PTR(8);
  308.         start_line = BE_16(&s->buf[stream_ptr]);
  309.         stream_ptr += 4;
  310.         lines_to_change = BE_16(&s->buf[stream_ptr]);
  311.         stream_ptr += 4;
  312.     } else {
  313.         start_line = 0;
  314.         lines_to_change = s->avctx->height;
  315.     }
  316.     row_ptr = row_inc * start_line;
  317.     while (lines_to_change--) {
  318.         CHECK_STREAM_PTR(2);
  319.         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3;
  320.         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  321.             if (rle_code == 0) {
  322.                 /* there's another skip code in the stream */
  323.                 CHECK_STREAM_PTR(1);
  324.                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 3;
  325.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  326.             } else if (rle_code < 0) {
  327.                 /* decode the run length code */
  328.                 rle_code = -rle_code;
  329.                 CHECK_STREAM_PTR(3);
  330.                 r = s->buf[stream_ptr++];
  331.                 g = s->buf[stream_ptr++];
  332.                 b = s->buf[stream_ptr++];
  333.                 CHECK_PIXEL_PTR(rle_code * 3);
  334.                 while (rle_code--) {
  335.                     rgb[pixel_ptr++] = r;
  336.                     rgb[pixel_ptr++] = g;
  337.                     rgb[pixel_ptr++] = b;
  338.                 }
  339.             } else {
  340.                 CHECK_STREAM_PTR(rle_code * 3);
  341.                 CHECK_PIXEL_PTR(rle_code * 3);
  342.                 /* copy pixels directly to output */
  343.                 while (rle_code--) {
  344.                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
  345.                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
  346.                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
  347.                 }
  348.             }
  349.         }
  350.         row_ptr += row_inc;
  351.     }
  352. }
  353. static void qtrle_decode_32bpp(QtrleContext *s)
  354. {
  355.     int stream_ptr;
  356.     int header;
  357.     int start_line;
  358.     int lines_to_change;
  359.     signed char rle_code;
  360.     int row_ptr, pixel_ptr;
  361.     int row_inc = s->frame.linesize[0];
  362.     unsigned char r, g, b;
  363.     unsigned int argb;
  364.     unsigned char *rgb = s->frame.data[0];
  365.     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  366.     /* check if this frame is even supposed to change */
  367.     if (s->size < 8)
  368.         return;
  369.     /* start after the chunk size */
  370.     stream_ptr = 4;
  371.     /* fetch the header */
  372.     CHECK_STREAM_PTR(2);
  373.     header = BE_16(&s->buf[stream_ptr]);
  374.     stream_ptr += 2;
  375.     /* if a header is present, fetch additional decoding parameters */
  376.     if (header & 0x0008) {
  377.         CHECK_STREAM_PTR(8);
  378.         start_line = BE_16(&s->buf[stream_ptr]);
  379.         stream_ptr += 4;
  380.         lines_to_change = BE_16(&s->buf[stream_ptr]);
  381.         stream_ptr += 4;
  382.     } else {
  383.         start_line = 0;
  384.         lines_to_change = s->avctx->height;
  385.     }
  386.     row_ptr = row_inc * start_line;
  387.     while (lines_to_change--) {
  388.         CHECK_STREAM_PTR(2);
  389.         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4;
  390.         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  391.             if (rle_code == 0) {
  392.                 /* there's another skip code in the stream */
  393.                 CHECK_STREAM_PTR(1);
  394.                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 4;
  395.                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
  396.             } else if (rle_code < 0) {
  397.                 /* decode the run length code */
  398.                 rle_code = -rle_code;
  399.                 CHECK_STREAM_PTR(4);
  400.                 stream_ptr++;  /* skip the alpha (?) byte */
  401.                 r = s->buf[stream_ptr++];
  402.                 g = s->buf[stream_ptr++];
  403.                 b = s->buf[stream_ptr++];
  404.                 argb = (r << 16) | (g << 8) | (b << 0);
  405.                 CHECK_PIXEL_PTR(rle_code * 4);
  406.                 while (rle_code--) {
  407.                     *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  408.                     pixel_ptr += 4;
  409.                 }
  410.             } else {
  411.                 CHECK_STREAM_PTR(rle_code * 4);
  412.                 CHECK_PIXEL_PTR(rle_code * 4);
  413.                 /* copy pixels directly to output */
  414.                 while (rle_code--) {
  415.                     stream_ptr++;  /* skip the alpha (?) byte */
  416.                     r = s->buf[stream_ptr++];
  417.                     g = s->buf[stream_ptr++];
  418.                     b = s->buf[stream_ptr++];
  419.                     argb = (r << 16) | (g << 8) | (b << 0);
  420.                     *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  421.                     pixel_ptr += 4;
  422.                 }
  423.             }
  424.         }
  425.         row_ptr += row_inc;
  426.     }
  427. }
  428. static int qtrle_decode_init(AVCodecContext *avctx)
  429. {
  430.     QtrleContext *s = (QtrleContext *)avctx->priv_data;
  431.     s->avctx = avctx;
  432.     switch (avctx->bits_per_sample) {
  433.     case 1:
  434.     case 2:
  435.     case 4:
  436.     case 8:
  437.     case 33:
  438.     case 34:
  439.     case 36:
  440.     case 40:
  441.         avctx->pix_fmt = PIX_FMT_PAL8;
  442.         break;
  443.     case 16:
  444.         avctx->pix_fmt = PIX_FMT_RGB555;
  445.         break;
  446.     case 24:
  447.         avctx->pix_fmt = PIX_FMT_RGB24;
  448.         break;
  449.     case 32:
  450.         avctx->pix_fmt = PIX_FMT_RGBA32;
  451.         break;
  452.     default:
  453.         av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?n",
  454.             avctx->bits_per_sample);
  455.         break;
  456.     }
  457.     avctx->has_b_frames = 0;
  458.     dsputil_init(&s->dsp, avctx);
  459.     s->frame.data[0] = NULL;
  460.     return 0;
  461. }
  462. static int qtrle_decode_frame(AVCodecContext *avctx,
  463.                               void *data, int *data_size,
  464.                               uint8_t *buf, int buf_size)
  465. {
  466.     QtrleContext *s = (QtrleContext *)avctx->priv_data;
  467.     s->buf = buf;
  468.     s->size = buf_size;
  469.     s->frame.reference = 1;
  470.     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
  471.                             FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
  472.     if (avctx->reget_buffer(avctx, &s->frame)) {
  473.         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failedn");
  474.         return -1;
  475.     }
  476.     switch (avctx->bits_per_sample) {
  477.     case 1:
  478.     case 33:
  479.         qtrle_decode_1bpp(s);
  480.         break;
  481.     case 2:
  482.     case 34:
  483.         qtrle_decode_2bpp(s);
  484.         break;
  485.     case 4:
  486.     case 36:
  487.         qtrle_decode_4bpp(s);
  488.         /* make the palette available on the way out */
  489.         memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  490.         if (s->avctx->palctrl->palette_changed) {
  491.             s->frame.palette_has_changed = 1;
  492.             s->avctx->palctrl->palette_changed = 0;
  493.         }
  494.         break;
  495.     case 8:
  496.     case 40:
  497.         qtrle_decode_8bpp(s);
  498.         /* make the palette available on the way out */
  499.         memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  500.         if (s->avctx->palctrl->palette_changed) {
  501.             s->frame.palette_has_changed = 1;
  502.             s->avctx->palctrl->palette_changed = 0;
  503.         }
  504.         break;
  505.     case 16:
  506.         qtrle_decode_16bpp(s);
  507.         break;
  508.     case 24:
  509.         qtrle_decode_24bpp(s);
  510.         break;
  511.     case 32:
  512.         qtrle_decode_32bpp(s);
  513.         break;
  514.     default:
  515.         av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?n",
  516.             avctx->bits_per_sample);
  517.         break;
  518.     }
  519.     *data_size = sizeof(AVFrame);
  520.     *(AVFrame*)data = s->frame;
  521.     /* always report that the buffer was completely consumed */
  522.     return buf_size;
  523. }
  524. static int qtrle_decode_end(AVCodecContext *avctx)
  525. {
  526.     QtrleContext *s = (QtrleContext *)avctx->priv_data;
  527.     if (s->frame.data[0])
  528.         avctx->release_buffer(avctx, &s->frame);
  529.     return 0;
  530. }
  531. AVCodec qtrle_decoder = {
  532.     "qtrle",
  533.     CODEC_TYPE_VIDEO,
  534.     CODEC_ID_QTRLE,
  535.     sizeof(QtrleContext),
  536.     qtrle_decode_init,
  537.     NULL,
  538.     qtrle_decode_end,
  539.     qtrle_decode_frame,
  540.     CODEC_CAP_DR1,
  541. };