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.

228 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. if (start_x >= avctx->width || start_y >= avctx->height)
  85. continue;
  86. for (int j = start_y; j < end_y; j += step_h) {
  87. for (int k = start_x; k < end_x; k += step_w) {
  88. if (mask & 0x8000U) {
  89. for (int m = 0; m < step_h; m++) {
  90. for (int n = 0; n < step_w; n++) {
  91. if (j + m >= avctx->height || k + n >= avctx->width)
  92. continue;
  93. AV_WB24(&frame->data[0][frame->linesize[0] * (h - (j + m)) + 3 * (k + n)], color);
  94. }
  95. }
  96. pixels_overwritten += FFMIN(step_h, avctx->height - j) * FFMIN(step_w, avctx->width - k);
  97. }
  98. mask = mask << 1;
  99. }
  100. }
  101. }
  102. return pixels_overwritten;
  103. }
  104. static int decode_frame(AVCodecContext *avctx, void *data,
  105. int *got_frame, AVPacket *avpkt)
  106. {
  107. ARBCContext *s = avctx->priv_data;
  108. AVFrame *frame = data;
  109. int ret, nb_segments;
  110. int prev_pixels = avctx->width * avctx->height;
  111. if (avpkt->size < 10)
  112. return AVERROR_INVALIDDATA;
  113. bytestream2_init(&s->gb, avpkt->data, avpkt->size);
  114. bytestream2_skip(&s->gb, 8);
  115. nb_segments = bytestream2_get_le16(&s->gb);
  116. if (nb_segments == 0)
  117. return avpkt->size;
  118. if (7 * nb_segments > bytestream2_get_bytes_left(&s->gb))
  119. return AVERROR_INVALIDDATA;
  120. if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
  121. return ret;
  122. if (s->prev_frame->data[0]) {
  123. ret = av_frame_copy(frame, s->prev_frame);
  124. if (ret < 0)
  125. return ret;
  126. }
  127. for (int i = 0; i < nb_segments; i++) {
  128. int resolution_flag;
  129. int fill;
  130. if (bytestream2_get_bytes_left(&s->gb) <= 0)
  131. return AVERROR_INVALIDDATA;
  132. fill = bytestream2_get_byte(&s->gb) << 16;
  133. bytestream2_skip(&s->gb, 1);
  134. fill |= bytestream2_get_byte(&s->gb) << 8;
  135. bytestream2_skip(&s->gb, 1);
  136. fill |= bytestream2_get_byte(&s->gb) << 0;
  137. bytestream2_skip(&s->gb, 1);
  138. resolution_flag = bytestream2_get_byte(&s->gb);
  139. if (resolution_flag & 0x10)
  140. prev_pixels -= fill_tileX(avctx, 1024, 1024, fill, frame);
  141. if (resolution_flag & 0x08)
  142. prev_pixels -= fill_tileX(avctx, 256, 256, fill, frame);
  143. if (resolution_flag & 0x04)
  144. prev_pixels -= fill_tileX(avctx, 64, 64, fill, frame);
  145. if (resolution_flag & 0x02)
  146. prev_pixels -= fill_tileX(avctx, 16, 16, fill, frame);
  147. if (resolution_flag & 0x01)
  148. prev_pixels -= fill_tile4(avctx, fill, frame);
  149. }
  150. av_frame_unref(s->prev_frame);
  151. if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
  152. return ret;
  153. frame->pict_type = prev_pixels <= 0 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
  154. frame->key_frame = prev_pixels <= 0;
  155. *got_frame = 1;
  156. return avpkt->size;
  157. }
  158. static av_cold int decode_init(AVCodecContext *avctx)
  159. {
  160. ARBCContext *s = avctx->priv_data;
  161. avctx->pix_fmt = AV_PIX_FMT_RGB24;
  162. s->prev_frame = av_frame_alloc();
  163. if (!s->prev_frame)
  164. return AVERROR(ENOMEM);
  165. return 0;
  166. }
  167. static void decode_flush(AVCodecContext *avctx)
  168. {
  169. ARBCContext *s = avctx->priv_data;
  170. av_frame_unref(s->prev_frame);
  171. }
  172. static av_cold int decode_close(AVCodecContext *avctx)
  173. {
  174. ARBCContext *s = avctx->priv_data;
  175. av_frame_free(&s->prev_frame);
  176. return 0;
  177. }
  178. AVCodec ff_arbc_decoder = {
  179. .name = "arbc",
  180. .long_name = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
  181. .type = AVMEDIA_TYPE_VIDEO,
  182. .id = AV_CODEC_ID_ARBC,
  183. .priv_data_size = sizeof(ARBCContext),
  184. .init = decode_init,
  185. .decode = decode_frame,
  186. .flush = decode_flush,
  187. .close = decode_close,
  188. .capabilities = AV_CODEC_CAP_DR1,
  189. .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
  190. };