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.

225 lines
7.0KB

  1. /*
  2. * Gryphon's Anim Compressor decoder
  3. * Copyright (c) 2019 Paul B Mahol
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "libavutil/imgutils.h"
  25. #include "libavutil/internal.h"
  26. #include "libavutil/intreadwrite.h"
  27. #include "libavutil/mem.h"
  28. #include "avcodec.h"
  29. #include "bytestream.h"
  30. #include "internal.h"
  31. typedef struct ARBCContext {
  32. GetByteContext gb;
  33. AVFrame *prev_frame;
  34. } ARBCContext;
  35. static int fill_tile4(AVCodecContext *avctx, int color, AVFrame *frame)
  36. {
  37. ARBCContext *s = avctx->priv_data;
  38. GetByteContext *gb = &s->gb;
  39. int nb_tiles = bytestream2_get_le16(gb);
  40. int h = avctx->height - 1;
  41. int pixels_overwritten = 0;
  42. if ((avctx->width / 4 + 1) * (avctx->height / 4 + 1) < nb_tiles)
  43. return 0;
  44. for (int i = 0; i < nb_tiles; i++) {
  45. int y = bytestream2_get_byte(gb);
  46. int x = bytestream2_get_byte(gb);
  47. uint16_t mask = bytestream2_get_le16(gb);
  48. int start_y = y * 4, start_x = x * 4;
  49. int end_y = start_y + 4, end_x = start_x + 4;
  50. for (int j = start_y; j < end_y; j++) {
  51. for (int k = start_x; k < end_x; k++) {
  52. if (mask & 0x8000) {
  53. if (j >= avctx->height || k >= avctx->width) {
  54. mask = mask << 1;
  55. continue;
  56. }
  57. AV_WB24(&frame->data[0][frame->linesize[0] * (h - j) + 3 * k], color);
  58. pixels_overwritten ++;
  59. }
  60. mask = mask << 1;
  61. }
  62. }
  63. }
  64. return pixels_overwritten;
  65. }
  66. static int fill_tileX(AVCodecContext *avctx, int tile_width, int tile_height,
  67. int color, AVFrame *frame)
  68. {
  69. ARBCContext *s = avctx->priv_data;
  70. GetByteContext *gb = &s->gb;
  71. const int step_h = tile_height / 4;
  72. const int step_w = tile_width / 4;
  73. int nb_tiles = bytestream2_get_le16(gb);
  74. int h = avctx->height - 1;
  75. int pixels_overwritten = 0;
  76. if ((avctx->width / tile_width + 1) * (avctx->height / tile_height + 1) < nb_tiles)
  77. return 0;
  78. for (int i = 0; i < nb_tiles; i++) {
  79. int y = bytestream2_get_byte(gb);
  80. int x = bytestream2_get_byte(gb);
  81. uint16_t mask = bytestream2_get_le16(gb);
  82. int start_y = y * tile_height, start_x = x * tile_width;
  83. int end_y = start_y + tile_height, end_x = start_x + tile_width;
  84. for (int j = start_y; j < end_y; j += step_h) {
  85. for (int k = start_x; k < end_x; k += step_w) {
  86. if (mask & 0x8000U) {
  87. for (int m = 0; m < step_h; m++) {
  88. for (int n = 0; n < step_w; n++) {
  89. if (j + m >= avctx->height || k + n >= avctx->width)
  90. continue;
  91. AV_WB24(&frame->data[0][frame->linesize[0] * (h - (j + m)) + 3 * (k + n)], color);
  92. }
  93. }
  94. pixels_overwritten += FFMIN(step_h, avctx->height - j) * FFMIN(step_w, avctx->width - k);
  95. }
  96. mask = mask << 1;
  97. }
  98. }
  99. }
  100. return pixels_overwritten;
  101. }
  102. static int decode_frame(AVCodecContext *avctx, void *data,
  103. int *got_frame, AVPacket *avpkt)
  104. {
  105. ARBCContext *s = avctx->priv_data;
  106. AVFrame *frame = data;
  107. int ret, nb_segments;
  108. int prev_pixels = avctx->width * avctx->height;
  109. if (avpkt->size < 10)
  110. return AVERROR_INVALIDDATA;
  111. bytestream2_init(&s->gb, avpkt->data, avpkt->size);
  112. bytestream2_skip(&s->gb, 8);
  113. nb_segments = bytestream2_get_le16(&s->gb);
  114. if (nb_segments == 0)
  115. return avpkt->size;
  116. if (7 * nb_segments > bytestream2_get_bytes_left(&s->gb))
  117. return AVERROR_INVALIDDATA;
  118. if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
  119. return ret;
  120. if (s->prev_frame->data[0]) {
  121. ret = av_frame_copy(frame, s->prev_frame);
  122. if (ret < 0)
  123. return ret;
  124. }
  125. for (int i = 0; i < nb_segments; i++) {
  126. int resolution_flag;
  127. int fill;
  128. if (bytestream2_get_bytes_left(&s->gb) <= 0)
  129. return AVERROR_INVALIDDATA;
  130. fill = bytestream2_get_byte(&s->gb) << 16;
  131. bytestream2_skip(&s->gb, 1);
  132. fill |= bytestream2_get_byte(&s->gb) << 8;
  133. bytestream2_skip(&s->gb, 1);
  134. fill |= bytestream2_get_byte(&s->gb) << 0;
  135. bytestream2_skip(&s->gb, 1);
  136. resolution_flag = bytestream2_get_byte(&s->gb);
  137. if (resolution_flag & 0x10)
  138. prev_pixels -= fill_tileX(avctx, 1024, 1024, fill, frame);
  139. if (resolution_flag & 0x08)
  140. prev_pixels -= fill_tileX(avctx, 256, 256, fill, frame);
  141. if (resolution_flag & 0x04)
  142. prev_pixels -= fill_tileX(avctx, 64, 64, fill, frame);
  143. if (resolution_flag & 0x02)
  144. prev_pixels -= fill_tileX(avctx, 16, 16, fill, frame);
  145. if (resolution_flag & 0x01)
  146. prev_pixels -= fill_tile4(avctx, fill, frame);
  147. }
  148. av_frame_unref(s->prev_frame);
  149. if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
  150. return ret;
  151. frame->pict_type = prev_pixels <= 0 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
  152. frame->key_frame = prev_pixels <= 0;
  153. *got_frame = 1;
  154. return avpkt->size;
  155. }
  156. static av_cold int decode_init(AVCodecContext *avctx)
  157. {
  158. ARBCContext *s = avctx->priv_data;
  159. avctx->pix_fmt = AV_PIX_FMT_RGB24;
  160. s->prev_frame = av_frame_alloc();
  161. if (!s->prev_frame)
  162. return AVERROR(ENOMEM);
  163. return 0;
  164. }
  165. static void decode_flush(AVCodecContext *avctx)
  166. {
  167. ARBCContext *s = avctx->priv_data;
  168. av_frame_unref(s->prev_frame);
  169. }
  170. static av_cold int decode_close(AVCodecContext *avctx)
  171. {
  172. ARBCContext *s = avctx->priv_data;
  173. av_frame_free(&s->prev_frame);
  174. return 0;
  175. }
  176. AVCodec ff_arbc_decoder = {
  177. .name = "arbc",
  178. .long_name = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
  179. .type = AVMEDIA_TYPE_VIDEO,
  180. .id = AV_CODEC_ID_ARBC,
  181. .priv_data_size = sizeof(ARBCContext),
  182. .init = decode_init,
  183. .decode = decode_frame,
  184. .flush = decode_flush,
  185. .close = decode_close,
  186. .capabilities = AV_CODEC_CAP_DR1,
  187. .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
  188. };