Advertisement
Guest User

Untitled

a guest
Feb 26th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.93 KB | None | 0 0
  1. /*
  2. * XPM image format
  3. *
  4. * Copyright (c) 2012 Paul B Mahol
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22.  
  23. #include "libavutil/parseutils.h"
  24. #include "avcodec.h"
  25.  
  26. AVframe *frame = data;
  27.  
  28. typedef struct XPMContext {
  29. /* AVframe *frame = data; */
  30. uint8_t *pixels;
  31. int pixels_size;
  32. } XPMDecContext;
  33.  
  34. static av_cold int xpm_decode_init(AVCodecContext *avctx)
  35. {
  36. XPMDecContext *x = avctx->priv_data;
  37.  
  38. avcodec_get_frame_defaults(&x->picture);
  39.  
  40. return 0;
  41. }
  42.  
  43. static int ascii2index(const uint8_t *cpixel, int cpp)
  44. {
  45. const uint8_t *p = cpixel;
  46. int n = 0, m = 1, i;
  47.  
  48. for (i = 0; i < cpp; i++) {
  49. if (*p < ' ' || *p > '~')
  50. return AVERROR_INVALIDDATA;
  51. n += (*p++ - ' ') * m;
  52. m *= 94;
  53. }
  54. return n;
  55. }
  56.  
  57. static int xpm_decode_frame(AVCodecContext *avctx, void *data,
  58. int *data_size, AVPacket *avpkt)
  59. {
  60. XPMDecContext *x = avctx->priv_data;
  61. const uint8_t *end, *ptr = avpkt->data;
  62. int ncolors, cpp, ret, i, j;
  63. uint8_t *dst, rgba[4];
  64.  
  65. end = avpkt->data + avpkt->size;
  66. if (memcmp(ptr, "/* XPM */", 9)) {
  67. av_log(avctx, AV_LOG_ERROR, "missing signature\n");
  68. return AVERROR_INVALIDDATA;
  69. }
  70.  
  71. ptr += strcspn(ptr, "\"");
  72. if (sscanf(ptr, "\"%u %u %u %u\",",
  73. &avctx->width, &avctx->height, &ncolors, &cpp) != 4) {
  74. av_log(avctx, AV_LOG_ERROR, "missing image parameters\n");
  75. return AVERROR_INVALIDDATA;
  76. }
  77.  
  78. if (ncolors <= 0 || cpp <= 0) {
  79. av_log(avctx, AV_LOG_ERROR, "invalid number of colors or chars per pixel\n");
  80. return AVERROR_INVALIDDATA;
  81. }
  82. if (ncolors > 256) {
  83. av_log(avctx, AV_LOG_ERROR, "unsupported number of colors\n");
  84. return AVERROR_PATCHWELCOME;
  85. }
  86.  
  87. if (cpp != 1 && cpp != 2) {
  88. av_log(avctx, AV_LOG_ERROR, "unsupported number of chars per pixel\n");
  89. return AVERROR_PATCHWELCOME;
  90. }
  91.  
  92. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  93.  
  94. if (p->data[0])
  95. avctx->release_buffer(avctx, p);
  96.  
  97. p->reference = 0;
  98. if ((ret = avctx->get_buffer(avctx, p)) < 0)
  99. return ret;
  100.  
  101. av_fast_padded_malloc(&x->pixels, &x->pixels_size, cpp == 2 ? 94 * 94 : 94);
  102. if (!x->pixels)
  103. return AVERROR(ENOMEM);
  104.  
  105. ptr += strcspn(ptr, ",") + 1;
  106. for (i = 0; i < ncolors; i++) {
  107. const uint8_t *index;
  108. int len;
  109.  
  110. ptr += strcspn(ptr, "\"") + 1;
  111. if (ptr + cpp > end)
  112. return AVERROR_INVALIDDATA;
  113. index = ptr;
  114. ptr += cpp;
  115.  
  116. ptr = strstr(ptr, "c ");
  117. if (ptr)
  118. ptr += 2;
  119. else
  120. return AVERROR_INVALIDDATA;
  121.  
  122. len = strcspn(ptr, "\" ");
  123. if ((ret = av_parse_color(rgba, ptr, len, avctx)) < 0)
  124. return ret;
  125. *(p->data[1] + i * 4 ) = rgba[2];
  126. *(p->data[1] + i * 4 + 1) = rgba[1];
  127. *(p->data[1] + i * 4 + 2) = rgba[0];
  128. *(p->data[1] + i * 4 + 3) = rgba[3];
  129.  
  130. if ((ret = ascii2index(index, cpp)) < 0)
  131. return ret;
  132. x->pixels[ret] = i;
  133.  
  134. ptr += strcspn(ptr, ",") + 1;
  135. }
  136.  
  137. for (i = 0; i < avctx->height; i++) {
  138. dst = p->data[0] + i * p->linesize[0];
  139. ptr += strcspn(ptr, "\"") + 1;
  140. for (j = 0; j < avctx->width; j++) {
  141. if (ptr + cpp > end)
  142. return AVERROR_INVALIDDATA;
  143. *dst++ = x->pixels[ascii2index(ptr, cpp)];
  144. ptr += cpp;
  145. }
  146. ptr += strcspn(ptr, ",") + 1;
  147. /* bytestream2_get_bufferu(&gb, ptr, rsize);
  148. bytestream2_skipu(&gb, lsize - rsize);
  149. ptr += p->linesize[0]; */
  150. }
  151.  
  152. p->key_frame = 1;
  153. frame_type = AV_PICTURE_TYPE_I;
  154.  
  155. *data_size = sizeof(AVFrame);
  156. *(AVFrame *)data = *p;
  157.  
  158. return avpkt->size;
  159. }
  160.  
  161. static av_cold int xpm_decode_close(AVCodecContext *avctx)
  162. {
  163. XPMDecContext *x = avctx->priv_data;
  164.  
  165.  
  166. av_freep(&x->pixels);
  167.  
  168. return 0;
  169. }
  170.  
  171. AVCodec ff_xpm_decoder = {
  172. .name = "xpm",
  173. .type = AVMEDIA_TYPE_VIDEO,
  174. .id = AV_CODEC_ID_XPM,
  175. .priv_data_size = sizeof(XPMDecContext),
  176. .init = xpm_decode_init,
  177. .close = xpm_decode_close,
  178. .decode = xpm_decode_frame,
  179. .capabilities = AV_CODEC_CAP_DR1,
  180. .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"),
  181. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement