## ffmpeg / libavcodec / jpeg_ls.c @ b6204677

History | View | Annotate | Download (11.8 KB)

1 | 5639729b | Michael Niedermayer | ```
/*
``` |
---|---|---|---|

2 | ```
* JPEG-LS encoder and decoder
``` |
||

3 | ```
* Copyright (c) 2003 Michael Niedermayer
``` |
||

4 | ```
*
``` |
||

5 | ```
* This library is free software; you can redistribute it and/or
``` |
||

6 | ```
* modify it under the terms of the GNU Lesser General Public
``` |
||

7 | ```
* License as published by the Free Software Foundation; either
``` |
||

8 | ```
* version 2 of the License, or (at your option) any later version.
``` |
||

9 | ```
*
``` |
||

10 | ```
* This library is distributed in the hope that it will be useful,
``` |
||

11 | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |
||

12 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

13 | ```
* Lesser General Public License for more details.
``` |
||

14 | ```
*
``` |
||

15 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

16 | ```
* License along with this library; if not, write to the Free Software
``` |
||

17 | ```
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
``` |
||

18 | ```
*/
``` |
||

19 | |||

20 | ```
/**
``` |
||

21 | ```
* @file jpeg_ls.c
``` |
||

22 | ```
* JPEG-LS encoder and decoder.
``` |
||

23 | ```
*/
``` |
||

24 | |||

25 | ```
#undef printf
``` |
||

26 | ```
#undef fprintf
``` |
||

27 | |||

28 | static inline int quantize(MJpegDecodeContext *s, int v){ //FIXME optimize |
||

29 | if(v==0) return 0; |
||

30 | if(v < 0){ |
||

31 | if (v >-s->t1) return -1; |
||

32 | else if(v >-s->t2) return -2; |
||

33 | else if(v >-s->t3) return -3; |
||

34 | else return -4; |
||

35 | ```
}else{
``` |
||

36 | if (v < s->t1) return 1; |
||

37 | else if(v < s->t2) return 2; |
||

38 | else if(v < s->t3) return 3; |
||

39 | else return 4; |
||

40 | } |
||

41 | } |
||

42 | |||

43 | static inline int predict8(uint8_t *src, uint8_t *last){ //FIXME perhaps its better to suppress these 2 |
||

44 | const int LT= last[-1]; |
||

45 | const int T= last[ 0]; |
||

46 | const int L = src[-1]; |
||

47 | |||

48 | ```
return mid_pred(L, L + T - LT, T);
``` |
||

49 | } |
||

50 | |||

51 | static inline int predict16(uint16_t *src, uint16_t *last){ |
||

52 | const int LT= last[-1]; |
||

53 | const int T= last[ 0]; |
||

54 | const int L = src[-1]; |
||

55 | |||

56 | ```
return mid_pred(L, L + T - LT, T);
``` |
||

57 | } |
||

58 | |||

59 | static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ |
||

60 | return 0; |
||

61 | } |
||

62 | |||

63 | static int iso_clip(int v, int vmin, int vmax){ |
||

64 | if(v > vmax || v < vmin) return vmin; |
||

65 | else return v; |
||

66 | } |
||

67 | |||

68 | static void reset_ls_coding_parameters(MJpegDecodeContext *s, int reset_all){ |
||

69 | const int basic_t1= 3; |
||

70 | const int basic_t2= 7; |
||

71 | const int basic_t3= 21; |
||

72 | ```
int factor;
``` |
||

73 | |||

74 | if(s->maxval==0 || reset_all) s->maxval= (1<<s->bits) - 1; |
||

75 | |||

76 | if(s->maxval >=128){ |
||

77 | factor= (FFMIN(s->maxval, 4096) + 128)>>8; |
||

78 | |||

79 | if(s->t1==0 || reset_all) |
||

80 | s->t1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval); |
||

81 | if(s->t2==0 || reset_all) |
||

82 | s->t2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->t1, s->maxval); |
||

83 | if(s->t3==0 || reset_all) |
||

84 | s->t3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->t2, s->maxval); |
||

85 | ```
}else{
``` |
||

86 | factor= 256 / (s->maxval + 1); |
||

87 | |||

88 | if(s->t1==0 || reset_all) |
||

89 | s->t1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval); |
||

90 | if(s->t2==0 || reset_all) |
||

91 | s->t2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->t1, s->maxval); |
||

92 | if(s->t3==0 || reset_all) |
||

93 | s->t3= iso_clip(FFMAX(4, basic_t3/factor + 6*s->near), s->t2, s->maxval); |
||

94 | } |
||

95 | |||

96 | if(s->reset==0 || reset_all) s->reset= 64; |
||

97 | } |
||

98 | |||

99 | static int decode_lse(MJpegDecodeContext *s) |
||

100 | { |
||

101 | ```
int len, id;
``` |
||

102 | |||

103 | ```
/* XXX: verify len field validity */
``` |
||

104 | ```
len = get_bits(&s->gb, 16);
``` |
||

105 | ```
id = get_bits(&s->gb, 8);
``` |
||

106 | |||

107 | ```
switch(id){
``` |
||

108 | case 1: |
||

109 | ```
s->maxval= get_bits(&s->gb, 16);
``` |
||

110 | ```
s->t1= get_bits(&s->gb, 16);
``` |
||

111 | ```
s->t2= get_bits(&s->gb, 16);
``` |
||

112 | ```
s->t3= get_bits(&s->gb, 16);
``` |
||

113 | ```
s->reset= get_bits(&s->gb, 16);
``` |
||

114 | |||

115 | ```
reset_ls_coding_parameters(s, 0);
``` |
||

116 | ```
//FIXME quant table?
``` |
||

117 | ```
break;
``` |
||

118 | case 2: |
||

119 | case 3: |
||

120 | ```
printf("palette not supported\n");
``` |
||

121 | return -1; |
||

122 | case 4: |
||

123 | ```
printf("oversize image not supported\n");
``` |
||

124 | return -1; |
||

125 | ```
default:
``` |
||

126 | ```
printf("invalid id %d\n", id);
``` |
||

127 | return -1; |
||

128 | } |
||

129 | |||

130 | return 0; |
||

131 | } |
||

132 | ```
#if 0
``` |
||

133 | ```
static inline void update_vlc_state(VlcState * const state, const int v, int half_count){
``` |
||

134 | ```
int drift= state->drift;
``` |
||

135 | ```
int count= state->count;
``` |
||

136 | ```
state->error_sum += ABS(v);
``` |
||

137 | ```
drift += v;
``` |
||

138 | |||

139 | ```
if(count == half_count){
``` |
||

140 | ```
count >>= 1;
``` |
||

141 | ```
drift >>= 1;
``` |
||

142 | ```
state->error_sum >>= 1;
``` |
||

143 | ```
}
``` |
||

144 | ```
count++;
``` |
||

145 | |||

146 | ```
if(drift <= -count){
``` |
||

147 | ```
if(state->bias > -128) state->bias--;
``` |
||

148 | ```
``` |
||

149 | ```
drift += count;
``` |
||

150 | ```
if(drift <= -count)
``` |
||

151 | ```
drift= -count + 1;
``` |
||

152 | ```
}else if(drift > 0){
``` |
||

153 | ```
if(state->bias < 127) state->bias++;
``` |
||

154 | ```
``` |
||

155 | ```
drift -= count;
``` |
||

156 | ```
if(drift > 0)
``` |
||

157 | ```
drift= 0;
``` |
||

158 | ```
}
``` |
||

159 | |||

160 | ```
state->drift= drift;
``` |
||

161 | ```
state->count= count;
``` |
||

162 | ```
}
``` |
||

163 | |||

164 | ```
#define R(p, i) (is_uint8 ? (((uint8_t*)p)[i] : ((uint16_t*)p)[i])
``` |
||

165 | |||

166 | ```
static inline int ls_decode_line(MJpegDecodeContext *s, void *lastv, void *dstv, int last2,
``` |
||

167 | ```
int w, int point_transform, int is_uint8){
``` |
||

168 | ```
int i, x, y;
``` |
||

169 | |||

170 | ```
for(x=0; x < w; x++){
``` |
||

171 | ```
int l, t, lt, rt;
``` |
||

172 | ```
``` |
||

173 | ```
t= R(last, 0);
``` |
||

174 | ```
if(x){
``` |
||

175 | ```
l = t;
``` |
||

176 | ```
lt= last2;
``` |
||

177 | ```
}else{
``` |
||

178 | ```
l = R(dst, x-1);
``` |
||

179 | ```
lt= R(last, x-1);
``` |
||

180 | ```
}
``` |
||

181 | |||

182 | ```
if(x<w-1) rt= R(last, x+1);
``` |
||

183 | ```
else rt= t;
``` |
||

184 | ```
``` |
||

185 | ```
hr_gradient= rt - t;
``` |
||

186 | ```
hl_gradient= t - lt;
``` |
||

187 | ```
v_gradient= lt - l;
``` |
||

188 | ```
``` |
||

189 | ```
context= quantize(s, v_gradient) + 9*(quantize(s, hl_gradient) + 9*quantize(s, hr_gradient));
``` |
||

190 | |||

191 | ```
if(context){
``` |
||

192 | ```
int pred= mid_pred(l, l + t - lt, t);
``` |
||

193 | |||

194 | ```
if(context < 0){
``` |
||

195 | ```
context= -context;
``` |
||

196 | ```
sign= 1;
``` |
||

197 | ```
pred= clip(0, pred - state->bias, maxval);
``` |
||

198 | ```
}else{
``` |
||

199 | ```
sign= 0;
``` |
||

200 | ```
pred= clip(0, pred + state->bias, maxval);
``` |
||

201 | ```
}
``` |
||

202 | |||

203 | ```
i= state->count;
``` |
||

204 | ```
k=0;
``` |
||

205 | ```
while(i < state->error_sum){ //FIXME optimize
``` |
||

206 | ```
k++;
``` |
||

207 | ```
i += i;
``` |
||

208 | ```
}
``` |
||

209 | ```
``` |
||

210 | ```
v= get_ur_golomb_jpegls(gb, k, LIMIT-qbpp, qbpp);
``` |
||

211 | ```
#if 1
``` |
||

212 | ```
v++;
``` |
||

213 | ```
if(v&1) v= (v>>1);
``` |
||

214 | ```
else v= -(v>>1);
``` |
||

215 | |||

216 | ```
if(k==0 && 2*state->drift <= - state->count) v ^= (-1);
``` |
||

217 | ```
#else
``` |
||

218 | v ^= (k==0 && 2*state->drift <= - state->count); |
||

219 | v++; |
||

220 | if(v&1) v= (v>>1); |
||

221 | else v= -(v>>1); |
||

222 | |||

223 | ```
#endif
``` |
||

224 | update_vlc_state(state, v, half_count); |
||

225 | |||

226 | ```
if(sign) v= -v;
``` |
||

227 | |||

228 | ```
if(is_uint8) ((uint8_t *)dst)[x]= (pred + v) & maxval;
``` |
||

229 | ```
else ((uint16_t*)dst)[x]= (pred + v) & maxval;
``` |
||

230 | ```
}else{
``` |
||

231 | ```
int run_count;
``` |
||

232 | |||

233 | ```
while(get_bits1(&s->gb)){
``` |
||

234 | ```
run_count = 1<<log2_run[run_index];
``` |
||

235 | ```
if(x + run_count > w) run_count= w - x;
``` |
||

236 | ```
else run_index++;
``` |
||

237 | |||

238 | ```
for(; run_count; run_count--){
``` |
||

239 | ```
if(is_uint8) ((uint8_t *)dst)[x++]= l;
``` |
||

240 | ```
else ((uint16_t*)dst)[x++]= l;
``` |
||

241 | } |
||

242 | |||

243 | if(x >= w) return 0; |
||

244 | } |
||

245 | |||

246 | run_count= get_bits(&s->gb, log2_run[run_index]); |
||

247 | |||

248 | ```
for(; run_count; run_count--){
``` |
||

249 | ```
if(is_uint8) ((uint8_t *)dst)[x++]= l;
``` |
||

250 | ```
else ((uint16_t*)dst)[x++]= l;
``` |
||

251 | } |
||

252 | |||

253 | ```
if(run_index) run_index--;
``` |
||

254 | |||

255 | if(x >= w) return 0; |
||

256 | |||

257 | ```
t= R(last, 0);
``` |
||

258 | |||

259 | RItype= (l==t); |
||

260 | ```
if(l==t){
``` |
||

261 | ```
state= 366;
``` |
||

262 | ```
temp= state->error_sum + (state->count>>1);
``` |
||

263 | ```
}else{
``` |
||

264 | ```
state= 365;
``` |
||

265 | temp= state->error_sum; |
||

266 | } |
||

267 | |||

268 | pred= t; |
||

269 | sign= l > t; |
||

270 | |||

271 | i= state->count; |
||

272 | ```
k=0;
``` |
||

273 | while(i < temp){ //FIXME optimize |
||

274 | k++; |
||

275 | i += i; |
||

276 | } |
||

277 | |||

278 | ```
assert(Errval != 0);
``` |
||

279 | map = (k==0 && 2*Nn < state->count) == (Errval>0); |
||

280 | |||

281 | |||

282 | if(run_count==0 && run_mode==1){ |
||

283 | ```
if(get_bits1(&s->gb)){
``` |
||

284 | ```
run_count = 1<<log2_run[run_index];
``` |
||

285 | ```
if(x + run_count <= w) run_index++;
``` |
||

286 | ```
}else{
``` |
||

287 | ```
if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]);
``` |
||

288 | else run_count=0; |
||

289 | ```
if(run_index) run_index--;
``` |
||

290 | ```
run_mode=2;
``` |
||

291 | } |
||

292 | } |
||

293 | run_count--; |
||

294 | if(run_count < 0){ |
||

295 | ```
run_mode=0;
``` |
||

296 | ```
run_count=0;
``` |
||

297 | diff= get_vlc_symbol(&s->gb, &p->vlc_state[context]); |
||

298 | if(diff>=0) diff++; |
||

299 | ```
}else
``` |
||

300 | ```
diff=0;
``` |
||

301 | |||

302 | } |
||

303 | } |
||

304 | |||

305 | ```
/* if (s->restart_interval && !s->restart_count)
``` |
||

306 | ```
s->restart_count = s->restart_interval;*/
``` |
||

307 | |||

308 | if(mb_x==0 || mb_y==0 || s->interlaced){ |
||

309 | for(i=0;i<nb_components;i++) { |
||

310 | uint8_t *ptr; |
||

311 | ```
int n, h, v, x, y, c, j, linesize;
``` |
||

312 | n = s->nb_blocks[i]; |
||

313 | c = s->comp_index[i]; |
||

314 | h = s->h_scount[i]; |
||

315 | v = s->v_scount[i]; |
||

316 | ```
x = 0;
``` |
||

317 | ```
y = 0;
``` |
||

318 | linesize= s->linesize[c]; |
||

319 | |||

320 | for(j=0; j<n; j++) { |
||

321 | ```
int pred;
``` |
||

322 | |||

323 | ```
ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
``` |
||

324 | if(y==0 && mb_y==0){ |
||

325 | if(x==0 && mb_x==0){ |
||

326 | ```
pred= 128 << point_transform;
``` |
||

327 | ```
}else{
``` |
||

328 | ```
pred= ptr[-1];
``` |
||

329 | } |
||

330 | ```
}else{
``` |
||

331 | if(x==0 && mb_x==0){ |
||

332 | pred= ptr[-linesize]; |
||

333 | ```
}else{
``` |
||

334 | PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); |
||

335 | } |
||

336 | } |
||

337 | |||

338 | ```
if (s->interlaced && s->bottom_field)
``` |
||

339 | ```
ptr += linesize >> 1;
``` |
||

340 | *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); |
||

341 | |||

342 | ```
if (++x == h) {
``` |
||

343 | ```
x = 0;
``` |
||

344 | y++; |
||

345 | } |
||

346 | } |
||

347 | } |
||

348 | ```
}else{
``` |
||

349 | for(i=0;i<nb_components;i++) { |
||

350 | uint8_t *ptr; |
||

351 | ```
int n, h, v, x, y, c, j, linesize;
``` |
||

352 | n = s->nb_blocks[i]; |
||

353 | c = s->comp_index[i]; |
||

354 | h = s->h_scount[i]; |
||

355 | v = s->v_scount[i]; |
||

356 | ```
x = 0;
``` |
||

357 | ```
y = 0;
``` |
||

358 | linesize= s->linesize[c]; |
||

359 | |||

360 | for(j=0; j<n; j++) { |
||

361 | ```
int pred;
``` |
||

362 | |||

363 | ```
ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
``` |
||

364 | PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); |
||

365 | *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); |
||

366 | ```
if (++x == h) {
``` |
||

367 | ```
x = 0;
``` |
||

368 | y++; |
||

369 | } |
||

370 | } |
||

371 | } |
||

372 | } |
||

373 | ```
if (s->restart_interval && !--s->restart_count) {
``` |
||

374 | align_get_bits(&s->gb); |
||

375 | skip_bits(&s->gb, 16); /* skip RSTn */ |
||

376 | } |
||

377 | return 0; |
||

378 | } |
||

379 | ```
#endif
``` |
||

380 | |||

381 | ```
#ifdef CONFIG_ENCODERS
``` |
||

382 | ```
AVCodec jpegls_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them
``` |
||

383 | ```
"jpegls",
``` |
||

384 | CODEC_TYPE_VIDEO, |
||

385 | CODEC_ID_JPEGLS, |
||

386 | ```
sizeof(MpegEncContext),
``` |
||

387 | MPV_encode_init, |
||

388 | encode_picture_ls, |
||

389 | MPV_encode_end, |
||

390 | }; |
||

391 | `#endif` |