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.

274 lines
7.7KB

  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <stdint.h>
  19. #include <zlib.h>
  20. #include "libavutil/frame.h"
  21. #include "libavutil/error.h"
  22. #include "libavutil/log.h"
  23. #include "avcodec.h"
  24. #include "bytestream.h"
  25. #include "codec.h"
  26. #include "internal.h"
  27. #include "packet.h"
  28. #include "png.h"
  29. #include "pngdsp.h"
  30. typedef struct LSCRContext {
  31. PNGDSPContext dsp;
  32. AVCodecContext *avctx;
  33. AVFrame *last_picture;
  34. uint8_t *buffer;
  35. int buffer_size;
  36. uint8_t *crow_buf;
  37. int crow_size;
  38. uint8_t *last_row;
  39. unsigned int last_row_size;
  40. GetByteContext gb;
  41. uint8_t *image_buf;
  42. int image_linesize;
  43. int row_size;
  44. int cur_h;
  45. int y;
  46. z_stream zstream;
  47. } LSCRContext;
  48. static void handle_row(LSCRContext *s)
  49. {
  50. uint8_t *ptr, *last_row;
  51. ptr = s->image_buf + s->image_linesize * s->y;
  52. if (s->y == 0)
  53. last_row = s->last_row;
  54. else
  55. last_row = ptr - s->image_linesize;
  56. ff_png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
  57. last_row, s->row_size, 3);
  58. s->y++;
  59. }
  60. static int decode_idat(LSCRContext *s, int length)
  61. {
  62. int ret;
  63. s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
  64. s->zstream.next_in = s->gb.buffer;
  65. bytestream2_skip(&s->gb, length);
  66. /* decode one line if possible */
  67. while (s->zstream.avail_in > 0) {
  68. ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
  69. if (ret != Z_OK && ret != Z_STREAM_END) {
  70. av_log(s->avctx, AV_LOG_ERROR, "inflate returned error %d\n", ret);
  71. return AVERROR_EXTERNAL;
  72. }
  73. if (s->zstream.avail_out == 0) {
  74. if (s->y < s->cur_h) {
  75. handle_row(s);
  76. }
  77. s->zstream.avail_out = s->crow_size;
  78. s->zstream.next_out = s->crow_buf;
  79. }
  80. if (ret == Z_STREAM_END && s->zstream.avail_in > 0) {
  81. av_log(s->avctx, AV_LOG_WARNING,
  82. "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
  83. return 0;
  84. }
  85. }
  86. return 0;
  87. }
  88. static int decode_frame_lscr(AVCodecContext *avctx,
  89. void *data, int *got_frame,
  90. AVPacket *avpkt)
  91. {
  92. LSCRContext *const s = avctx->priv_data;
  93. GetByteContext *gb = &s->gb;
  94. AVFrame *frame = s->last_picture;
  95. int ret, nb_blocks, offset = 0;
  96. if (avpkt->size < 2)
  97. return AVERROR_INVALIDDATA;
  98. if (avpkt->size == 2)
  99. return 0;
  100. bytestream2_init(gb, avpkt->data, avpkt->size);
  101. nb_blocks = bytestream2_get_le16(gb);
  102. if (bytestream2_get_bytes_left(gb) < 2 + nb_blocks * (12 + 8))
  103. return AVERROR_INVALIDDATA;
  104. ret = ff_reget_buffer(avctx, frame,
  105. nb_blocks ? 0 : FF_REGET_BUFFER_FLAG_READONLY);
  106. if (ret < 0)
  107. return ret;
  108. for (int b = 0; b < nb_blocks; b++) {
  109. int x, y, x2, y2, w, h, left;
  110. uint32_t csize, size;
  111. s->zstream.zalloc = ff_png_zalloc;
  112. s->zstream.zfree = ff_png_zfree;
  113. s->zstream.opaque = NULL;
  114. if ((ret = inflateInit(&s->zstream)) != Z_OK) {
  115. av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
  116. ret = AVERROR_EXTERNAL;
  117. goto end;
  118. }
  119. bytestream2_seek(gb, 2 + b * 12, SEEK_SET);
  120. x = bytestream2_get_le16(gb);
  121. y = bytestream2_get_le16(gb);
  122. x2 = bytestream2_get_le16(gb);
  123. y2 = bytestream2_get_le16(gb);
  124. w = x2-x;
  125. s->cur_h = h = y2-y;
  126. if (w <= 0 || x < 0 || x >= avctx->width || w + x > avctx->width ||
  127. h <= 0 || y < 0 || y >= avctx->height || h + y > avctx->height) {
  128. ret = AVERROR_INVALIDDATA;
  129. goto end;
  130. }
  131. size = bytestream2_get_le32(gb);
  132. frame->key_frame = (nb_blocks == 1) &&
  133. (w == avctx->width) &&
  134. (h == avctx->height) &&
  135. (x == 0) && (y == 0);
  136. bytestream2_seek(gb, 2 + nb_blocks * 12 + offset, SEEK_SET);
  137. csize = bytestream2_get_be32(gb);
  138. if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) {
  139. ret = AVERROR_INVALIDDATA;
  140. goto end;
  141. }
  142. offset += size;
  143. left = size;
  144. s->y = 0;
  145. s->row_size = w * 3;
  146. av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
  147. if (!s->buffer) {
  148. ret = AVERROR(ENOMEM);
  149. goto end;
  150. }
  151. av_fast_padded_malloc(&s->last_row, &s->last_row_size, s->row_size);
  152. if (!s->last_row) {
  153. ret = AVERROR(ENOMEM);
  154. goto end;
  155. }
  156. s->crow_size = w * 3 + 1;
  157. s->crow_buf = s->buffer + 15;
  158. s->zstream.avail_out = s->crow_size;
  159. s->zstream.next_out = s->crow_buf;
  160. s->image_buf = frame->data[0] + (avctx->height - y - 1) * frame->linesize[0] + x * 3;
  161. s->image_linesize =-frame->linesize[0];
  162. while (left > 16) {
  163. ret = decode_idat(s, csize);
  164. if (ret < 0)
  165. goto end;
  166. left -= csize + 16;
  167. if (left > 16) {
  168. bytestream2_skip(gb, 4);
  169. csize = bytestream2_get_be32(gb);
  170. if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) {
  171. ret = AVERROR_INVALIDDATA;
  172. goto end;
  173. }
  174. }
  175. }
  176. inflateEnd(&s->zstream);
  177. }
  178. frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
  179. if ((ret = av_frame_ref(data, frame)) < 0)
  180. return ret;
  181. *got_frame = 1;
  182. end:
  183. inflateEnd(&s->zstream);
  184. if (ret < 0)
  185. return ret;
  186. return avpkt->size;
  187. }
  188. static int lscr_decode_close(AVCodecContext *avctx)
  189. {
  190. LSCRContext *s = avctx->priv_data;
  191. av_frame_free(&s->last_picture);
  192. av_freep(&s->buffer);
  193. av_freep(&s->last_row);
  194. return 0;
  195. }
  196. static int lscr_decode_init(AVCodecContext *avctx)
  197. {
  198. LSCRContext *s = avctx->priv_data;
  199. avctx->color_range = AVCOL_RANGE_JPEG;
  200. avctx->pix_fmt = AV_PIX_FMT_BGR24;
  201. s->avctx = avctx;
  202. s->last_picture = av_frame_alloc();
  203. if (!s->last_picture)
  204. return AVERROR(ENOMEM);
  205. ff_pngdsp_init(&s->dsp);
  206. return 0;
  207. }
  208. static void lscr_decode_flush(AVCodecContext *avctx)
  209. {
  210. LSCRContext *s = avctx->priv_data;
  211. av_frame_unref(s->last_picture);
  212. }
  213. AVCodec ff_lscr_decoder = {
  214. .name = "lscr",
  215. .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"),
  216. .type = AVMEDIA_TYPE_VIDEO,
  217. .id = AV_CODEC_ID_LSCR,
  218. .priv_data_size = sizeof(LSCRContext),
  219. .init = lscr_decode_init,
  220. .close = lscr_decode_close,
  221. .decode = decode_frame_lscr,
  222. .flush = lscr_decode_flush,
  223. .capabilities = AV_CODEC_CAP_DR1,
  224. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
  225. };