hdrdec.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Radiance HDR image format
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <stdlib.h>
  21. #include "libavutil/imgutils.h"
  22. #include "avcodec.h"
  23. #include "internal.h"
  24. #include "bytestream.h"
  25. #include "codec_internal.h"
  26. #include "thread.h"
  27. #define MINELEN 8
  28. #define MAXELEN 0x7fff
  29. static int hdr_get_line(GetByteContext *gb, uint8_t *buffer, int size)
  30. {
  31. int n = 0, c;
  32. memset(buffer, 0, size);
  33. do {
  34. c = bytestream2_get_byte(gb);
  35. if (n < size - 1)
  36. buffer[n++] = c;
  37. } while (bytestream2_get_bytes_left(gb) > 0 && c != '\n');
  38. return 0;
  39. }
  40. static float convert(int expo, int val)
  41. {
  42. if (expo == -128) {
  43. return 0.f;
  44. } else {
  45. const float v = val / 256.f;
  46. return ldexpf(v, expo);
  47. }
  48. }
  49. static int decompress(uint8_t *scanline, int w, GetByteContext *gb, const uint8_t *start)
  50. {
  51. int rshift = 0;
  52. while (w > 0) {
  53. scanline[0] = bytestream2_get_byte(gb);
  54. scanline[1] = bytestream2_get_byte(gb);
  55. scanline[2] = bytestream2_get_byte(gb);
  56. scanline[3] = bytestream2_get_byte(gb);
  57. if (scanline[0] == 1 &&
  58. scanline[1] == 1 &&
  59. scanline[2] == 1) {
  60. int run = scanline[3];
  61. for (int i = run << rshift; i > 0 && w > 0 && scanline >= start + 4; i--) {
  62. memcpy(scanline, scanline - 4, 4);
  63. scanline += 4;
  64. }
  65. w -= run << rshift;
  66. rshift += 8;
  67. if (rshift > 16)
  68. break;
  69. } else {
  70. scanline += 4;
  71. w--;
  72. rshift = 0;
  73. }
  74. }
  75. return 1;
  76. }
  77. static int hdr_decode_frame(AVCodecContext *avctx, AVFrame *p,
  78. int *got_frame, AVPacket *avpkt)
  79. {
  80. const uint8_t *buf = avpkt->data;
  81. int ret, buf_size = avpkt->size;
  82. int width = 0, height = 0;
  83. GetByteContext gb;
  84. uint8_t line[512];
  85. float sar;
  86. bytestream2_init(&gb, buf, buf_size);
  87. hdr_get_line(&gb, line, sizeof(line));
  88. if (memcmp("#?RADIANCE\n", line, 11))
  89. return AVERROR_INVALIDDATA;
  90. do {
  91. hdr_get_line(&gb, line, sizeof(line));
  92. if (sscanf(line, "PIXASPECT=%f\n", &sar) == 1)
  93. avctx->sample_aspect_ratio = p->sample_aspect_ratio = av_inv_q(av_d2q(sar, 4096));
  94. } while (line[0] != '\n');
  95. hdr_get_line(&gb, line, sizeof(line));
  96. if (sscanf(line, "-Y %d +X %d\n", &height, &width) == 2) {
  97. ;
  98. } else if (sscanf(line, "+Y %d +X %d\n", &height, &width) == 2) {
  99. ;
  100. } else if (sscanf(line, "-Y %d -X %d\n", &height, &width) == 2) {
  101. ;
  102. } else if (sscanf(line, "+Y %d -X %d\n", &height, &width) == 2) {
  103. ;
  104. } else if (sscanf(line, "-X %d +Y %d\n", &width, &height) == 2) {
  105. ;
  106. } else if (sscanf(line, "+X %d +Y %d\n", &width, &height) == 2) {
  107. ;
  108. } else if (sscanf(line, "-X %d -Y %d\n", &width, &height) == 2) {
  109. ;
  110. } else if (sscanf(line, "+X %d -Y %d\n", &width, &height) == 2) {
  111. ;
  112. }
  113. if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
  114. return ret;
  115. avctx->pix_fmt = AV_PIX_FMT_GBRPF32;
  116. if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
  117. return ret;
  118. for (int y = 0; y < height; y++) {
  119. float *dst_r = (float *)(p->data[2] + y * p->linesize[2]);
  120. float *dst_g = (float *)(p->data[0] + y * p->linesize[0]);
  121. float *dst_b = (float *)(p->data[1] + y * p->linesize[1]);
  122. uint8_t *scanline = p->data[0] + y * p->linesize[0];
  123. int i;
  124. if (width < MINELEN || width > MAXELEN) {
  125. decompress(scanline, width, &gb, scanline);
  126. goto convert;
  127. }
  128. i = bytestream2_peek_byte(&gb);
  129. if (i != 2) {
  130. decompress(scanline, width, &gb, scanline);
  131. goto convert;
  132. }
  133. bytestream2_skip(&gb, 1);
  134. scanline[1] = bytestream2_get_byte(&gb);
  135. scanline[2] = bytestream2_get_byte(&gb);
  136. i = bytestream2_get_byte(&gb);
  137. if (scanline[1] != 2 || scanline[2] & 128) {
  138. scanline[0] = 2;
  139. scanline[3] = i;
  140. decompress(scanline + 4, width - 1, &gb, scanline);
  141. goto convert;
  142. }
  143. for (int i = 0; i < 4; i++) {
  144. uint8_t *scanline = p->data[0] + y * p->linesize[0] + i;
  145. for (int j = 0; j < width * 4 && bytestream2_get_bytes_left(&gb) > 0;) {
  146. int run = bytestream2_get_byte(&gb);
  147. if (run > 128) {
  148. uint8_t val = bytestream2_get_byte(&gb);
  149. run &= 127;
  150. while (run--) {
  151. if (j >= width * 4)
  152. break;
  153. scanline[j] = val;
  154. j += 4;
  155. }
  156. } else if (run > 0) {
  157. while (run--) {
  158. if (j >= width * 4)
  159. break;
  160. scanline[j] = bytestream2_get_byte(&gb);
  161. j += 4;
  162. }
  163. }
  164. }
  165. }
  166. convert:
  167. for (int x = 0; x < width; x++) {
  168. uint8_t rgbe[4];
  169. int expo;
  170. memcpy(rgbe, p->data[0] + y * p->linesize[0] + x * 4, 4);
  171. expo = rgbe[3] - 128;
  172. dst_r[x] = convert(expo, rgbe[0]);
  173. dst_b[x] = convert(expo, rgbe[2]);
  174. dst_g[x] = convert(expo, rgbe[1]);
  175. }
  176. }
  177. p->key_frame = 1;
  178. p->pict_type = AV_PICTURE_TYPE_I;
  179. *got_frame = 1;
  180. return buf_size;
  181. }
  182. const FFCodec ff_hdr_decoder = {
  183. .p.name = "hdr",
  184. .p.long_name = NULL_IF_CONFIG_SMALL("HDR (Radiance RGBE format) image"),
  185. .p.type = AVMEDIA_TYPE_VIDEO,
  186. .p.id = AV_CODEC_ID_RADIANCE_HDR,
  187. .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
  188. FF_CODEC_DECODE_CB(hdr_decode_frame),
  189. };