You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.5KB

  1. /*
  2. * IFF PBM/ILBM bitmap decoder
  3. * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  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. * @file libavcodec/iff.c
  23. * IFF PBM/ILBM bitmap decoder
  24. */
  25. #include "bytestream.h"
  26. #include "avcodec.h"
  27. /**
  28. * Convert CMAP buffer (stored in extradata) to lavc palette format
  29. */
  30. int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
  31. {
  32. int count, i;
  33. if (avctx->bits_per_coded_sample > 8) {
  34. av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
  35. return AVERROR_INVALIDDATA;
  36. }
  37. count = 1 << avctx->bits_per_coded_sample;
  38. if (avctx->extradata_size < count * 3) {
  39. av_log(avctx, AV_LOG_ERROR, "palette data underflow\n");
  40. return AVERROR_INVALIDDATA;
  41. }
  42. for (i=0; i < count; i++) {
  43. pal[i] = AV_RB24( avctx->extradata + i*3 );
  44. }
  45. return 0;
  46. }
  47. static av_cold int decode_init(AVCodecContext *avctx)
  48. {
  49. AVFrame *frame = avctx->priv_data;
  50. avctx->pix_fmt = PIX_FMT_PAL8;
  51. frame->reference = 1;
  52. if (avctx->get_buffer(avctx, frame) < 0) {
  53. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  54. return AVERROR_UNKNOWN;
  55. }
  56. return ff_cmap_read_palette(avctx, (uint32_t*)frame->data[1]);
  57. }
  58. /**
  59. * Interleaved memcpy
  60. */
  61. static void imemcpy(uint8_t *dst, const uint8_t const *buf, int x, int bps, int plane, int length)
  62. {
  63. int i, b;
  64. for(i = 0; i < length; i++) {
  65. int value = buf[i];
  66. for (b = 0; b < bps; b++) {
  67. if (value & (1<<b))
  68. dst[ (x+i)*bps + 7 - b] |= 1<<plane;
  69. }
  70. }
  71. }
  72. /**
  73. * Interleaved memset
  74. */
  75. static void imemset(uint8_t *dst, int value, int x, int bps, int plane, int length)
  76. {
  77. int i, b;
  78. for(i = 0; i < length; i++) {
  79. for (b = 0; b < bps; b++) {
  80. if (value & (1<<b))
  81. dst[ (x+i)*bps + 7 - b] |= 1<<plane;
  82. }
  83. }
  84. }
  85. static int decode_frame_ilbm(AVCodecContext *avctx,
  86. void *data, int *data_size,
  87. AVPacket *avpkt)
  88. {
  89. AVFrame *frame = avctx->priv_data;
  90. const uint8_t *buf = avpkt->data;
  91. int buf_size = avpkt->size;
  92. int planewidth = avctx->width / avctx->bits_per_coded_sample;
  93. int y, plane;
  94. if (avctx->reget_buffer(avctx, frame) < 0){
  95. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  96. return -1;
  97. }
  98. if (buf_size < avctx->width * avctx->height) {
  99. av_log(avctx, AV_LOG_ERROR, "buffer underflow\n");
  100. return -1;
  101. }
  102. for(y = 0; y < avctx->height; y++ ) {
  103. uint8_t *row = &frame->data[0][ y*frame->linesize[0] ];
  104. memset(row, 0, avctx->width);
  105. for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
  106. imemcpy(row, buf, 0, avctx->bits_per_coded_sample, plane, planewidth);
  107. buf += planewidth;
  108. }
  109. }
  110. *data_size = sizeof(AVFrame);
  111. *(AVFrame*)data = *frame;
  112. return buf_size;
  113. }
  114. static int decode_frame_byterun1(AVCodecContext *avctx,
  115. void *data, int *data_size,
  116. AVPacket *avpkt)
  117. {
  118. AVFrame *frame = avctx->priv_data;
  119. const uint8_t *buf = avpkt->data;
  120. int buf_size = avpkt->size;
  121. const uint8_t *buf_end = buf+buf_size;
  122. int planewidth = avctx->width / avctx->bits_per_coded_sample;
  123. int y, plane, x;
  124. if (avctx->reget_buffer(avctx, frame) < 0){
  125. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  126. return -1;
  127. }
  128. for(y = 0; y < avctx->height ; y++ ) {
  129. uint8_t *row = &frame->data[0][ y*frame->linesize[0] ];
  130. if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
  131. memset(row, 0, avctx->width);
  132. for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
  133. for(x = 0; x < planewidth && buf < buf_end; ) {
  134. int8_t value = *buf++;
  135. int length;
  136. if (value >= 0) {
  137. length = value + 1;
  138. imemcpy(row, buf, x, avctx->bits_per_coded_sample, plane, FFMIN3(length, buf_end - buf, planewidth - x));
  139. buf += length;
  140. } else if (value > -128) {
  141. length = -value + 1;
  142. imemset(row, *buf++, x, avctx->bits_per_coded_sample, plane, FFMIN(length, planewidth - x));
  143. } else { //noop
  144. continue;
  145. }
  146. x += length;
  147. }
  148. }
  149. } else {
  150. for(x = 0; x < avctx->width && buf < buf_end; ) {
  151. int8_t value = *buf++;
  152. int length;
  153. if (value >= 0) {
  154. length = value + 1;
  155. memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x));
  156. buf += length;
  157. } else if (value > -128) {
  158. length = -value + 1;
  159. memset(row + x, *buf++, FFMIN(length, avctx->width - x));
  160. } else { //noop
  161. continue;
  162. }
  163. x += length;
  164. }
  165. }
  166. }
  167. *data_size = sizeof(AVFrame);
  168. *(AVFrame*)data = *frame;
  169. return buf_size;
  170. }
  171. static av_cold int decode_end(AVCodecContext *avctx)
  172. {
  173. AVFrame *frame = avctx->priv_data;
  174. if (frame->data[0])
  175. avctx->release_buffer(avctx, frame);
  176. return 0;
  177. }
  178. AVCodec iff_ilbm_decoder = {
  179. "iff_ilbm",
  180. CODEC_TYPE_VIDEO,
  181. CODEC_ID_IFF_ILBM,
  182. sizeof(AVFrame),
  183. decode_init,
  184. NULL,
  185. decode_end,
  186. decode_frame_ilbm,
  187. CODEC_CAP_DR1,
  188. .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
  189. };
  190. AVCodec iff_byterun1_decoder = {
  191. "iff_byterun1",
  192. CODEC_TYPE_VIDEO,
  193. CODEC_ID_IFF_BYTERUN1,
  194. sizeof(AVFrame),
  195. decode_init,
  196. NULL,
  197. decode_end,
  198. decode_frame_byterun1,
  199. CODEC_CAP_DR1,
  200. .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
  201. };