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
26
28 #define MAXELEN 0x7fff
29
31 {
33
35
36 do {
37 c = bytestream2_get_byte(gb);
41
42 return 0;
43 }
44
46 {
47 if (expo == -128) {
48 return 0.f;
49 } else {
50 const float v =
val / 256.f;
51
53 }
54 }
55
57 {
58 int rshift = 0;
59
63 scanline[0] = bytestream2_get_byte(gb);
64 scanline[1] = bytestream2_get_byte(gb);
65 scanline[2] = bytestream2_get_byte(gb);
66 scanline[3] = bytestream2_get_byte(gb);
67
68 if (scanline[0] == 1 &&
69 scanline[1] == 1 &&
70 scanline[2] == 1) {
71 int run = scanline[3];
72 for (
int i =
run << rshift;
i > 0 &&
w > 0 && scanline >= start + 4;
i--) {
73 memcpy(scanline, scanline - 4, 4);
74 scanline += 4;
76 }
77 rshift += 8;
78 if (rshift > 16)
79 break;
80 } else {
81 scanline += 4;
83 rshift = 0;
84 }
85 }
86
87 return 1;
88 }
89
92 {
96 float sar;
98
101 if (memcmp(
"#?RADIANCE\n",
line, 11))
103
104 do {
106 if (sscanf(
line,
"PIXASPECT=%f\n", &sar) == 1)
108 }
while (
line[0] !=
'\n' &&
line[0]);
109
112 ;
114 ;
116 ;
118 ;
120 ;
122 ;
124 ;
126 ;
127 }
128
131
133
136
139
140 for (
int y = 0; y <
height; y++) {
141 float *dst_r = (
float *)(p->
data[2] + y * p->
linesize[2]);
142 float *dst_g = (
float *)(p->
data[0] + y * p->
linesize[0]);
143 float *dst_b = (
float *)(p->
data[1] + y * p->
linesize[1]);
146
147 if (width < MINELEN || width >
MAXELEN) {
152 }
153
154 i = bytestream2_peek_byte(&gb);
160 }
162
163 scanline[1] = bytestream2_get_byte(&gb);
164 scanline[2] = bytestream2_get_byte(&gb);
165 i = bytestream2_get_byte(&gb);
166
167 if (scanline[1] != 2 || scanline[2] & 128) {
168 scanline[0] = 2;
174 }
175
176 for (
int i = 0;
i < 4;
i++) {
178
180 int run = bytestream2_get_byte(&gb);
182 uint8_t
val = bytestream2_get_byte(&gb);
186 break;
188 j += 4;
189 }
190 }
else if (
run > 0) {
193 break;
194 scanline[j] = bytestream2_get_byte(&gb);
195 j += 4;
196 }
197 }
198 }
199 }
200
202 for (
int x = 0; x <
width; x++) {
203 uint8_t rgbe[4];
204 int expo;
205
206 memcpy(rgbe, p->
data[0] + y * p->
linesize[0] + x * 4, 4);
207 expo = rgbe[3] - 128;
208
209 dst_r[x] =
convert(expo, rgbe[0]);
210 dst_b[x] =
convert(expo, rgbe[2]);
211 dst_g[x] =
convert(expo, rgbe[1]);
212 }
213 }
214
217
218 *got_frame = 1;
219
221 }
222
231 };