It appears Solaris's cc is ignoring the signedness of bitfield types.
[xiph/unicode.git] / theora / lib / dec / state.c
blob807f30925d75d816fe5f1f8c72c63f23ae834261
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id$
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <string.h>
20 #include "../internal.h"
21 #include "idct.h"
22 #if defined(USE_ASM)
23 #if defined(_MSC_VER)
24 # include "x86_vc/x86int.h"
25 #else
26 # include "x86/x86int.h"
27 #endif
28 #endif
29 #if defined(OC_DUMP_IMAGES)
30 # include <stdio.h>
31 # include "png.h"
32 #endif
34 void oc_restore_fpu(const oc_theora_state *_state){
35 _state->opt_vtable.restore_fpu();
38 void oc_restore_fpu_c(void){}
40 /*Returns the fragment index of the top-left block in a macro block.
41 This can be used to test whether or not the whole macro block is coded.
42 _sb: The super block.
43 _quadi: The quadrant number.
44 Return: The index of the fragment of the upper left block in the macro
45 block, or -1 if the block lies outside the coded frame.*/
46 static int oc_sb_quad_top_left_frag(const oc_sb *_sb,int _quadi){
47 /*It so happens that under the Hilbert curve ordering described below, the
48 upper-left block in each macro block is at index 0, except in macro block
49 3, where it is at index 2.*/
50 return _sb->map[_quadi][_quadi&_quadi<<1];
53 /*Fills in the mapping from block positions to fragment numbers for a single
54 color plane.
55 This function also fills in the "valid" flag of each quadrant in a super
56 block.
57 _sbs: The array of super blocks for the color plane.
58 _frag0: The index of the first fragment in the plane.
59 _hfrags: The number of horizontal fragments in a coded frame.
60 _vfrags: The number of vertical fragments in a coded frame.*/
61 static void oc_sb_create_plane_mapping(oc_sb _sbs[],int _frag0,int _hfrags,
62 int _vfrags){
63 /*Contains the (macro_block,block) indices for a 4x4 grid of
64 fragments.
65 The pattern is a 4x4 Hilbert space-filling curve.
66 A Hilbert curve has the nice property that as the curve grows larger, its
67 fractal dimension approaches 2.
68 The intuition is that nearby blocks in the curve are also close spatially,
69 with the previous element always an immediate neighbor, so that runs of
70 blocks should be well correlated.*/
71 static const int SB_MAP[4][4][2]={
72 {{0,0},{0,1},{3,2},{3,3}},
73 {{0,3},{0,2},{3,1},{3,0}},
74 {{1,0},{1,3},{2,0},{2,3}},
75 {{1,1},{1,2},{2,1},{2,2}}
77 oc_sb *sb;
78 int yfrag;
79 int y;
80 sb=_sbs;
81 yfrag=_frag0;
82 for(y=0;;y+=4){
83 int imax;
84 int x;
85 /*Figure out how many columns of blocks in this super block lie within the
86 image.*/
87 imax=_vfrags-y;
88 if(imax>4)imax=4;
89 else if(imax<=0)break;
90 for(x=0;;x+=4,sb++){
91 int xfrag;
92 int jmax;
93 int quadi;
94 int i;
95 /*Figure out how many rows of blocks in this super block lie within the
96 image.*/
97 jmax=_hfrags-x;
98 if(jmax>4)jmax=4;
99 else if(jmax<=0)break;
100 /*By default, set all fragment indices to -1.*/
101 memset(sb->map[0],0xFF,sizeof(sb->map));
102 /*Fill in the fragment map for this super block.*/
103 xfrag=yfrag+x;
104 for(i=0;i<imax;i++){
105 int j;
106 for(j=0;j<jmax;j++){
107 sb->map[SB_MAP[i][j][0]][SB_MAP[i][j][1]]=xfrag+j;
109 xfrag+=_hfrags;
111 /*Mark which quadrants of this super block lie within the image.*/
112 for(quadi=0;quadi<4;quadi++){
113 sb->quad_valid|=(oc_sb_quad_top_left_frag(sb,quadi)>=0)<<quadi;
116 yfrag+=_hfrags<<2;
120 /*Fills in the Y plane fragment map for a macro block given the fragment
121 coordinates of its upper-left hand corner.
122 _mb: The macro block to fill.
123 _fplane: The description of the Y plane.
124 _x: The X location of the upper-left hand fragment in the Y plane.
125 _y: The Y location of the upper-left hand fragment in the Y plane.*/
126 static void oc_mb_fill_ymapping(oc_mb *_mb,const oc_fragment_plane *_fplane,
127 int _x,int _y){
128 int i;
129 for(i=0;i<2;i++){
130 int j;
131 if(_y+i>=_fplane->nvfrags)break;
132 for(j=0;j<2;j++){
133 if(_x+j>=_fplane->nhfrags)break;
134 _mb->map[0][i<<1|j]=(_y+i)*_fplane->nhfrags+_x+j;
139 /*Fills in the chroma plane fragment maps for a macro block.
140 This version is for use with chroma decimated in the X and Y directions.
141 _mb: The macro block to fill.
142 _fplanes: The descriptions of the fragment planes.
143 _x: The X location of the upper-left hand fragment in the Y plane.
144 _y: The Y location of the upper-left hand fragment in the Y plane.*/
145 static void oc_mb_fill_cmapping00(oc_mb *_mb,
146 const oc_fragment_plane _fplanes[3],int _x,int _y){
147 int fragi;
148 _x>>=1;
149 _y>>=1;
150 fragi=_y*_fplanes[1].nhfrags+_x;
151 _mb->map[1][0]=fragi+_fplanes[1].froffset;
152 _mb->map[2][0]=fragi+_fplanes[2].froffset;
155 /*Fills in the chroma plane fragment maps for a macro block.
156 This version is for use with chroma decimated in the Y direction.
157 _mb: The macro block to fill.
158 _fplanes: The descriptions of the fragment planes.
159 _x: The X location of the upper-left hand fragment in the Y plane.
160 _y: The Y location of the upper-left hand fragment in the Y plane.*/
161 static void oc_mb_fill_cmapping01(oc_mb *_mb,
162 const oc_fragment_plane _fplanes[3],int _x,int _y){
163 int fragi;
164 int j;
165 _y>>=1;
166 fragi=_y*_fplanes[1].nhfrags+_x;
167 for(j=0;j<2;j++){
168 if(_x+j>=_fplanes[1].nhfrags)break;
169 _mb->map[1][j]=fragi+_fplanes[1].froffset;
170 _mb->map[2][j]=fragi+_fplanes[2].froffset;
171 fragi++;
175 /*Fills in the chroma plane fragment maps for a macro block.
176 This version is for use with chroma decimated in the X direction.
177 _mb: The macro block to fill.
178 _fplanes: The descriptions of the fragment planes.
179 _x: The X location of the upper-left hand fragment in the Y plane.
180 _y: The Y location of the upper-left hand fragment in the Y plane.*/
181 static void oc_mb_fill_cmapping10(oc_mb *_mb,
182 const oc_fragment_plane _fplanes[3],int _x,int _y){
183 int fragi;
184 int i;
185 _x>>=1;
186 fragi=_y*_fplanes[1].nhfrags+_x;
187 for(i=0;i<2;i++){
188 if(_y+i>=_fplanes[1].nvfrags)break;
189 _mb->map[1][i<<1]=fragi+_fplanes[1].froffset;
190 _mb->map[2][i<<1]=fragi+_fplanes[2].froffset;
191 fragi+=_fplanes[1].nhfrags;
195 /*Fills in the chroma plane fragment maps for a macro block.
196 This version is for use with no chroma decimation.
197 This uses the already filled-in Y plane values.
198 _mb: The macro block to fill.
199 _fplanes: The descriptions of the fragment planes.*/
200 static void oc_mb_fill_cmapping11(oc_mb *_mb,
201 const oc_fragment_plane _fplanes[3]){
202 int k;
203 for(k=0;k<4;k++){
204 if(_mb->map[0][k]>=0){
205 _mb->map[1][k]=_mb->map[0][k]+_fplanes[1].froffset;
206 _mb->map[2][k]=_mb->map[0][k]+_fplanes[2].froffset;
211 /*The function type used to fill in the chroma plane fragment maps for a
212 macro block.
213 _mb: The macro block to fill.
214 _fplanes: The descriptions of the fragment planes.
215 _x: The X location of the upper-left hand fragment in the Y plane.
216 _y: The Y location of the upper-left hand fragment in the Y plane.*/
217 typedef void (*oc_mb_fill_cmapping_func)(oc_mb *_mb,
218 const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0);
220 /*A table of functions used to fill in the chroma plane fragment maps for a
221 macro block for each type of chrominance decimation.*/
222 static const oc_mb_fill_cmapping_func OC_MB_FILL_CMAPPING_TABLE[4]={
223 oc_mb_fill_cmapping00,
224 oc_mb_fill_cmapping01,
225 oc_mb_fill_cmapping10,
226 (oc_mb_fill_cmapping_func)oc_mb_fill_cmapping11
229 /*Fills in the mapping from macro blocks to their corresponding fragment
230 numbers in each plane.
231 _mbs: The array of macro blocks.
232 _fplanes: The descriptions of the fragment planes.
233 _ctype: The chroma decimation type.*/
234 static void oc_mb_create_mapping(oc_mb _mbs[],
235 const oc_fragment_plane _fplanes[3],int _ctype){
236 oc_mb_fill_cmapping_func mb_fill_cmapping;
237 oc_mb *mb0;
238 int y;
239 mb0=_mbs;
240 mb_fill_cmapping=OC_MB_FILL_CMAPPING_TABLE[_ctype];
241 /*Loop through the Y plane super blocks.*/
242 for(y=0;y<_fplanes[0].nvfrags;y+=4){
243 int x;
244 for(x=0;x<_fplanes[0].nhfrags;x+=4,mb0+=4){
245 int ymb;
246 /*Loop through the macro blocks in each super block in display order.*/
247 for(ymb=0;ymb<2;ymb++){
248 int xmb;
249 for(xmb=0;xmb<2;xmb++){
250 oc_mb *mb;
251 int mbx;
252 int mby;
253 mb=mb0+OC_MB_MAP[ymb][xmb];
254 mbx=x|xmb<<1;
255 mby=y|ymb<<1;
256 mb->x=mbx<<3;
257 mb->y=mby<<3;
258 /*Initialize fragment indexes to -1.*/
259 memset(mb->map,0xFF,sizeof(mb->map));
260 /*Make sure this macro block is within the encoded region.*/
261 if(mbx>=_fplanes[0].nhfrags||mby>=_fplanes[0].nvfrags){
262 mb->mode=OC_MODE_INVALID;
263 continue;
265 /*Fill in the fragment indices for the Y plane.*/
266 oc_mb_fill_ymapping(mb,_fplanes,mbx,mby);
267 /*Fill in the fragment indices for the chroma planes.*/
268 (*mb_fill_cmapping)(mb,_fplanes,mbx,mby);
275 /*Marks the fragments which fall all or partially outside the displayable
276 region of the frame.
277 _state: The Theora state containing the fragments to be marked.*/
278 static void oc_state_border_init(oc_theora_state *_state){
279 typedef struct{
280 int x0;
281 int y0;
282 int xf;
283 int yf;
284 }oc_crop_rect;
285 oc_fragment *frag;
286 oc_fragment *yfrag_end;
287 oc_fragment *xfrag_end;
288 oc_fragment_plane *fplane;
289 oc_crop_rect *crop;
290 oc_crop_rect crop_rects[3];
291 int pli;
292 int y;
293 int x;
294 /*The method we use here is slow, but the code is dead simple and handles
295 all the special cases easily.
296 We only ever need to do it once.*/
297 /*Loop through the fragments, marking those completely outside the
298 displayable region and constructing a border mask for those that straddle
299 the border.*/
300 _state->nborders=0;
301 yfrag_end=frag=_state->frags;
302 for(pli=0;pli<3;pli++){
303 fplane=_state->fplanes+pli;
304 crop=crop_rects+pli;
305 /*Set up the cropping rectangle for this plane.*/
306 crop->x0=_state->info.pic_x;
307 crop->xf=_state->info.pic_x+_state->info.pic_width;
308 crop->y0=_state->info.pic_y;
309 crop->yf=_state->info.pic_y+_state->info.pic_height;
310 if(pli>0){
311 if(!(_state->info.pixel_fmt&1)){
312 crop->x0=crop->x0>>1;
313 crop->xf=crop->xf+1>>1;
315 if(!(_state->info.pixel_fmt&2)){
316 crop->y0=crop->y0>>1;
317 crop->yf=crop->yf+1>>1;
320 y=0;
321 for(yfrag_end+=fplane->nfrags;frag<yfrag_end;y+=8){
322 x=0;
323 for(xfrag_end=frag+fplane->nhfrags;frag<xfrag_end;frag++,x+=8){
324 /*First check to see if this fragment is completely outside the
325 displayable region.*/
326 /*Note the special checks for an empty cropping rectangle.
327 This guarantees that if we count a fragment as straddling the
328 border below, at least one pixel in the fragment will be inside
329 the displayable region.*/
330 if(x+8<=crop->x0||crop->xf<=x||y+8<=crop->y0||crop->yf<=y||
331 crop->x0>=crop->xf||crop->y0>=crop->yf){
332 frag->invalid=1;
334 /*Otherwise, check to see if it straddles the border.*/
335 else if(x<crop->x0&&crop->x0<x+8||x<crop->xf&&crop->xf<x+8||
336 y<crop->y0&&crop->y0<y+8||y<crop->yf&&crop->yf<y+8){
337 ogg_int64_t mask;
338 int npixels;
339 int i;
340 mask=npixels=0;
341 for(i=0;i<8;i++){
342 int j;
343 for(j=0;j<8;j++){
344 if(x+j>=crop->x0&&x+j<crop->xf&&y+i>=crop->y0&&y+i<crop->yf){
345 mask|=(ogg_int64_t)1<<(i<<3|j);
346 npixels++;
350 /*Search the fragment array for border info with the same pattern.
351 In general, there will be at most 8 different patterns (per
352 plane).*/
353 for(i=0;;i++){
354 if(i>=_state->nborders){
355 _state->nborders++;
356 _state->borders[i].mask=mask;
357 _state->borders[i].npixels=npixels;
359 else if(_state->borders[i].mask!=mask)continue;
360 frag->border=_state->borders+i;
361 break;
369 static void oc_state_frarray_init(oc_theora_state *_state){
370 int yhfrags;
371 int yvfrags;
372 int chfrags;
373 int cvfrags;
374 int yfrags;
375 int cfrags;
376 int nfrags;
377 int yhsbs;
378 int yvsbs;
379 int chsbs;
380 int cvsbs;
381 int ysbs;
382 int csbs;
383 int nsbs;
384 int nmbs;
385 int hdec;
386 int vdec;
387 int pli;
388 /*Figure out the number of fragments in each plane.*/
389 /*These parameters have already been validated to be multiples of 16.*/
390 yhfrags=_state->info.frame_width>>3;
391 yvfrags=_state->info.frame_height>>3;
392 hdec=!(_state->info.pixel_fmt&1);
393 vdec=!(_state->info.pixel_fmt&2);
394 chfrags=yhfrags+hdec>>hdec;
395 cvfrags=yvfrags+vdec>>vdec;
396 yfrags=yhfrags*yvfrags;
397 cfrags=chfrags*cvfrags;
398 nfrags=yfrags+2*cfrags;
399 /*Figure out the number of super blocks in each plane.*/
400 yhsbs=yhfrags+3>>2;
401 yvsbs=yvfrags+3>>2;
402 chsbs=chfrags+3>>2;
403 cvsbs=cvfrags+3>>2;
404 ysbs=yhsbs*yvsbs;
405 csbs=chsbs*cvsbs;
406 nsbs=ysbs+2*csbs;
407 nmbs=ysbs<<2;
408 /*Initialize the fragment array.*/
409 _state->fplanes[0].nhfrags=yhfrags;
410 _state->fplanes[0].nvfrags=yvfrags;
411 _state->fplanes[0].froffset=0;
412 _state->fplanes[0].nfrags=yfrags;
413 _state->fplanes[0].nhsbs=yhsbs;
414 _state->fplanes[0].nvsbs=yvsbs;
415 _state->fplanes[0].sboffset=0;
416 _state->fplanes[0].nsbs=ysbs;
417 _state->fplanes[1].nhfrags=_state->fplanes[2].nhfrags=chfrags;
418 _state->fplanes[1].nvfrags=_state->fplanes[2].nvfrags=cvfrags;
419 _state->fplanes[1].froffset=yfrags;
420 _state->fplanes[2].froffset=yfrags+cfrags;
421 _state->fplanes[1].nfrags=_state->fplanes[2].nfrags=cfrags;
422 _state->fplanes[1].nhsbs=_state->fplanes[2].nhsbs=chsbs;
423 _state->fplanes[1].nvsbs=_state->fplanes[2].nvsbs=cvsbs;
424 _state->fplanes[1].sboffset=ysbs;
425 _state->fplanes[2].sboffset=ysbs+csbs;
426 _state->fplanes[1].nsbs=_state->fplanes[2].nsbs=csbs;
427 _state->nfrags=nfrags;
428 _state->frags=_ogg_calloc(nfrags,sizeof(oc_fragment));
429 _state->nsbs=nsbs;
430 _state->sbs=_ogg_calloc(nsbs,sizeof(oc_sb));
431 _state->nhmbs=yhsbs<<1;
432 _state->nvmbs=yvsbs<<1;
433 _state->nmbs=nmbs;
434 _state->mbs=_ogg_calloc(nmbs,sizeof(oc_mb));
435 _state->coded_fragis=_ogg_malloc(nfrags*sizeof(_state->coded_fragis[0]));
436 _state->uncoded_fragis=_state->coded_fragis+nfrags;
437 _state->coded_mbis=_ogg_malloc(nmbs*sizeof(_state->coded_mbis[0]));
438 /*Create the mapping from super blocks to fragments.*/
439 for(pli=0;pli<3;pli++){
440 oc_fragment_plane *fplane;
441 fplane=_state->fplanes+pli;
442 oc_sb_create_plane_mapping(_state->sbs+fplane->sboffset,
443 fplane->froffset,fplane->nhfrags,fplane->nvfrags);
445 /*Create the mapping from macro blocks to fragments.*/
446 oc_mb_create_mapping(_state->mbs,_state->fplanes,_state->info.pixel_fmt);
447 /*Initialize the invalid and border fields of each fragment.*/
448 oc_state_border_init(_state);
451 static void oc_state_frarray_clear(oc_theora_state *_state){
452 _ogg_free(_state->coded_mbis);
453 _ogg_free(_state->coded_fragis);
454 _ogg_free(_state->mbs);
455 _ogg_free(_state->sbs);
456 _ogg_free(_state->frags);
460 /*Initializes the buffers used for reconstructed frames.
461 These buffers are padded with 16 extra pixels on each side, to allow
462 unrestricted motion vectors without special casing the boundary.
463 If chroma is decimated in either direction, the padding is reduced by a
464 factor of 2 on the appropriate sides.
465 _enc: The encoding context to store the buffers in.*/
466 static void oc_state_ref_bufs_init(oc_theora_state *_state){
467 th_info *info;
468 unsigned char *ref_frame_data;
469 size_t yplane_sz;
470 size_t cplane_sz;
471 int yhstride;
472 int yvstride;
473 int chstride;
474 int cvstride;
475 int yoffset;
476 int coffset;
477 int rfi;
478 info=&_state->info;
479 /*Compute the image buffer parameters for each plane.*/
480 yhstride=info->frame_width+2*OC_UMV_PADDING;
481 yvstride=info->frame_height+2*OC_UMV_PADDING;
482 chstride=yhstride>>!(info->pixel_fmt&1);
483 cvstride=yvstride>>!(info->pixel_fmt&2);
484 yplane_sz=(size_t)yhstride*yvstride;
485 cplane_sz=(size_t)chstride*cvstride;
486 yoffset=OC_UMV_PADDING+OC_UMV_PADDING*yhstride;
487 coffset=(OC_UMV_PADDING>>!(info->pixel_fmt&1))+
488 (OC_UMV_PADDING>>!(info->pixel_fmt&2))*chstride;
489 _state->ref_frame_data=ref_frame_data=_ogg_malloc(3*(yplane_sz+2*cplane_sz));
490 /*Set up the width, height and stride for the image buffers.*/
491 _state->ref_frame_bufs[0][0].width=info->frame_width;
492 _state->ref_frame_bufs[0][0].height=info->frame_height;
493 _state->ref_frame_bufs[0][0].stride=yhstride;
494 _state->ref_frame_bufs[0][1].width=_state->ref_frame_bufs[0][2].width=
495 info->frame_width>>!(info->pixel_fmt&1);
496 _state->ref_frame_bufs[0][1].height=_state->ref_frame_bufs[0][2].height=
497 info->frame_height>>!(info->pixel_fmt&2);
498 _state->ref_frame_bufs[0][1].stride=_state->ref_frame_bufs[0][2].stride=
499 chstride;
500 memcpy(_state->ref_frame_bufs[1],_state->ref_frame_bufs[0],
501 sizeof(_state->ref_frame_bufs[0]));
502 memcpy(_state->ref_frame_bufs[2],_state->ref_frame_bufs[0],
503 sizeof(_state->ref_frame_bufs[0]));
504 /*Set up the data pointers for the image buffers.*/
505 for(rfi=0;rfi<3;rfi++){
506 _state->ref_frame_bufs[rfi][0].data=ref_frame_data+yoffset;
507 ref_frame_data+=yplane_sz;
508 _state->ref_frame_bufs[rfi][1].data=ref_frame_data+coffset;
509 ref_frame_data+=cplane_sz;
510 _state->ref_frame_bufs[rfi][2].data=ref_frame_data+coffset;
511 ref_frame_data+=cplane_sz;
512 /*Flip the buffer upside down.*/
513 oc_ycbcr_buffer_flip(_state->ref_frame_bufs[rfi],
514 _state->ref_frame_bufs[rfi]);
515 /*Initialize the fragment pointers into this buffer.*/
516 oc_state_fill_buffer_ptrs(_state,rfi,_state->ref_frame_bufs[rfi]);
518 /*Initialize the reference frame indexes.*/
519 _state->ref_frame_idx[OC_FRAME_GOLD]=
520 _state->ref_frame_idx[OC_FRAME_PREV]=
521 _state->ref_frame_idx[OC_FRAME_SELF]=-1;
524 static void oc_state_ref_bufs_clear(oc_theora_state *_state){
525 _ogg_free(_state->ref_frame_data);
529 void oc_state_vtable_init_c(oc_theora_state *_state){
530 _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c;
531 _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c;
532 _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_c;
533 _state->opt_vtable.state_frag_copy=oc_state_frag_copy_c;
534 _state->opt_vtable.state_frag_recon=oc_state_frag_recon_c;
535 _state->opt_vtable.state_loop_filter_frag_rows=
536 oc_state_loop_filter_frag_rows_c;
537 _state->opt_vtable.restore_fpu=oc_restore_fpu_c;
540 /*Initialize the accelerated function pointers.*/
541 void oc_state_vtable_init(oc_theora_state *_state){
542 #if defined(USE_ASM)
543 oc_state_vtable_init_x86(_state);
544 #else
545 oc_state_vtable_init_c(_state);
546 #endif
550 int oc_state_init(oc_theora_state *_state,const th_info *_info){
551 int old_granpos;
552 /*First validate the parameters.*/
553 if(_info==NULL)return TH_EFAULT;
554 /*The width and height of the encoded frame must be multiples of 16.
555 They must also, when divided by 16, fit into a 16-bit unsigned integer.
556 The displayable frame offset coordinates must fit into an 8-bit unsigned
557 integer.
558 Note that the offset Y in the API is specified on the opposite side from
559 how it is specified in the bitstream, because the Y axis is flipped in
560 the bitstream.
561 The displayable frame must fit inside the encoded frame.
562 The color space must be one known by the encoder.*/
563 if((_info->frame_width&0xF)||(_info->frame_height&0xF)||
564 _info->frame_width>=0x100000||_info->frame_height>=0x100000||
565 _info->pic_x+_info->pic_width>_info->frame_width||
566 _info->pic_y+_info->pic_height>_info->frame_height||
567 _info->pic_x>255||
568 _info->frame_height-_info->pic_height-_info->pic_y>255||
569 _info->colorspace<0||_info->colorspace>=TH_CS_NSPACES||
570 _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS){
571 return TH_EINVAL;
573 memset(_state,0,sizeof(*_state));
574 memcpy(&_state->info,_info,sizeof(*_info));
575 /*Invert the sense of pic_y to match Theora's right-handed coordinate
576 system.*/
577 _state->info.pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
578 _state->frame_type=OC_UNKWN_FRAME;
579 oc_state_vtable_init(_state);
580 oc_state_frarray_init(_state);
581 oc_state_ref_bufs_init(_state);
582 /*If the keyframe_granule_shift is out of range, use the maximum allowable
583 value.*/
584 if(_info->keyframe_granule_shift<0||_info->keyframe_granule_shift>31){
585 _state->info.keyframe_granule_shift=31;
587 _state->keyframe_num=1;
588 _state->curframe_num=0;
589 /*3.2.0 streams mark the frame index instead of the frame count.
590 This was changed with stream version 3.2.1 to conform to other Ogg
591 codecs.
592 We subtract an extra one from the frame number for old streams.*/
593 old_granpos=!TH_VERSION_CHECK(_info,3,2,1);
594 _state->curframe_num-=old_granpos;
595 _state->keyframe_num-=old_granpos;
596 return 0;
599 void oc_state_clear(oc_theora_state *_state){
600 oc_state_ref_bufs_clear(_state);
601 oc_state_frarray_clear(_state);
605 /*Duplicates the pixels on the border of the image plane out into the
606 surrounding padding for use by unrestricted motion vectors.
607 This function only adds the left and right borders, and only for the fragment
608 rows specified.
609 _refi: The index of the reference buffer to pad.
610 _pli: The color plane.
611 _y0: The Y coordinate of the first row to pad.
612 _yend: The Y coordinate of the row to stop padding at.*/
613 void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli,
614 int _y0,int _yend){
615 th_img_plane *iplane;
616 unsigned char *apix;
617 unsigned char *bpix;
618 unsigned char *epix;
619 int hpadding;
620 hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1));
621 iplane=_state->ref_frame_bufs[_refi]+_pli;
622 apix=iplane->data+_y0*iplane->stride;
623 bpix=apix+iplane->width-1;
624 epix=iplane->data+_yend*iplane->stride;
625 /*Note the use of != instead of <, which allows ystride to be negative.*/
626 while(apix!=epix){
627 memset(apix-hpadding,apix[0],hpadding);
628 memset(bpix+1,bpix[0],hpadding);
629 apix+=iplane->stride;
630 bpix+=iplane->stride;
634 /*Duplicates the pixels on the border of the image plane out into the
635 surrounding padding for use by unrestricted motion vectors.
636 This function only adds the top and bottom borders, and must be called after
637 the left and right borders are added.
638 _refi: The index of the reference buffer to pad.
639 _pli: The color plane.*/
640 void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli){
641 th_img_plane *iplane;
642 unsigned char *apix;
643 unsigned char *bpix;
644 unsigned char *epix;
645 int hpadding;
646 int vpadding;
647 int fullw;
648 hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1));
649 vpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&2));
650 iplane=_state->ref_frame_bufs[_refi]+_pli;
651 fullw=iplane->width+(hpadding<<1);
652 apix=iplane->data-hpadding;
653 bpix=iplane->data+(iplane->height-1)*iplane->stride-hpadding;
654 epix=apix-iplane->stride*vpadding;
655 while(apix!=epix){
656 memcpy(apix-iplane->stride,apix,fullw);
657 memcpy(bpix+iplane->stride,bpix,fullw);
658 apix-=iplane->stride;
659 bpix+=iplane->stride;
663 /*Duplicates the pixels on the border of the given reference image out into
664 the surrounding padding for use by unrestricted motion vectors.
665 _state: The context containing the reference buffers.
666 _refi: The index of the reference buffer to pad.*/
667 void oc_state_borders_fill(oc_theora_state *_state,int _refi){
668 int pli;
669 for(pli=0;pli<3;pli++){
670 oc_state_borders_fill_rows(_state,_refi,pli,0,
671 _state->ref_frame_bufs[_refi][pli].height);
672 oc_state_borders_fill_caps(_state,_refi,pli);
676 /*Sets the buffer pointer in each fragment to point to the portion of the
677 image buffer which it corresponds to.
678 _state: The Theora state to fill.
679 _buf_idx: The index of the buffer pointer to fill.
680 The first three correspond to our reconstructed frame buffers,
681 while the last corresponds to the input image.
682 _img: The image buffer to fill the fragments with.*/
683 void oc_state_fill_buffer_ptrs(oc_theora_state *_state,int _buf_idx,
684 th_ycbcr_buffer _img){
685 int pli;
686 /*Special handling for the input image to give us the opportunity to skip
687 some updates.
688 The other buffers do not change throughout the encoding process.*/
689 if(_buf_idx==OC_FRAME_IO){
690 if(memcmp(_state->input,_img,sizeof(th_ycbcr_buffer))==0)return;
691 memcpy(_state->input,_img,sizeof(th_ycbcr_buffer));
693 for(pli=0;pli<3;pli++){
694 th_img_plane *iplane;
695 oc_fragment_plane *fplane;
696 oc_fragment *frag;
697 oc_fragment *vfrag_end;
698 unsigned char *vpix;
699 iplane=&_img[pli];
700 fplane=&_state->fplanes[pli];
701 vpix=iplane->data;
702 frag=_state->frags+fplane->froffset;
703 vfrag_end=frag+fplane->nfrags;
704 while(frag<vfrag_end){
705 oc_fragment *hfrag_end;
706 unsigned char *hpix;
707 hpix=vpix;
708 for(hfrag_end=frag+fplane->nhfrags;frag<hfrag_end;frag++){
709 frag->buffer[_buf_idx]=hpix;
710 hpix+=8;
712 vpix+=iplane->stride<<3;
717 /*Returns the macro block index of the macro block in the given position.
718 _state: The Theora state the macro block is contained in.
719 _mbx: The X coordinate of the macro block (in macro blocks, not pixels).
720 _mby: The Y coordinate of the macro block (in macro blocks, not pixels).
721 Return: The index of the macro block in the given position.*/
722 int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby){
723 return ((_mbx&~1)<<1)+(_mby&~1)*_state->nhmbs+OC_MB_MAP[_mby&1][_mbx&1];
726 /*Determines the offsets in an image buffer to use for motion compensation.
727 _state: The Theora state the offsets are to be computed with.
728 _offsets: Returns the offset for the buffer(s).
729 _offsets[0] is always set.
730 _offsets[1] is set if the motion vector has non-zero fractional
731 components.
732 _dx: The X component of the motion vector.
733 _dy: The Y component of the motion vector.
734 _ystride: The Y stride in the buffer the motion vector points into.
735 _pli: The color plane index.
736 Return: The number of offsets returned: 1 or 2.*/
737 int oc_state_get_mv_offsets(oc_theora_state *_state,int _offsets[2],
738 int _dx,int _dy,int _ystride,int _pli){
739 int xprec;
740 int yprec;
741 int xfrac;
742 int yfrac;
743 /*Here is a brief description of how Theora handles motion vectors:
744 Motion vector components are specified to half-pixel accuracy in
745 undecimated directions of each plane, and quarter-pixel accuracy in
746 decimated directions.
747 Integer parts are extracted by dividing (not shifting) by the
748 appropriate amount, with truncation towards zero.
749 These integer values are used to calculate the first offset.
751 If either of the fractional parts are non-zero, then a second offset is
752 computed.
753 No third or fourth offsets are computed, even if both components have
754 non-zero fractional parts.
755 The second offset is computed by dividing (not shifting) by the
756 appropriate amount, always truncating _away_ from zero.*/
757 /*These two variables decide whether we are in half- or quarter-pixel
758 precision in each component.*/
759 xprec=1+(!(_state->info.pixel_fmt&1)&&_pli);
760 yprec=1+(!(_state->info.pixel_fmt&2)&&_pli);
761 /*These two variables are either 0 if all the fractional bits are 0 or 1 if
762 any of them are non-zero.*/
763 xfrac=!!(_dx&(1<<xprec)-1);
764 yfrac=!!(_dy&(1<<yprec)-1);
765 _offsets[0]=(_dx>>xprec)+(_dy>>yprec)*_ystride;
766 if(xfrac||yfrac){
767 /*This branchless code is equivalent to:
768 if(_dx<0)_offests[0]=-(-_dx>>xprec);
769 else _offsets[0]=(_dx>>xprec);
770 if(_dy<0)_offsets[0]-=(-_dy>>yprec)*_ystride;
771 else _offsets[0]+=(_dy>>yprec)*_ystride;
772 _offsets[1]=_offsets[0];
773 if(xfrac){
774 if(_dx<0)_offsets[1]++;
775 else _offsets[1]--;
777 if(yfrac){
778 if(_dy<0)_offsets[1]+=_ystride;
779 else _offsets[1]-=_ystride;
781 _offsets[1]=_offsets[0];
782 _offsets[_dx>=0]+=xfrac;
783 _offsets[_dy>=0]+=_ystride&-yfrac;
784 return 2;
786 else return 1;
789 void oc_state_frag_recon(oc_theora_state *_state,oc_fragment *_frag,
790 int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
791 ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]){
792 _state->opt_vtable.state_frag_recon(_state,_frag,_pli,_dct_coeffs,
793 _last_zzi,_ncoefs,_dc_iquant,_ac_iquant);
796 void oc_state_frag_recon_c(oc_theora_state *_state,oc_fragment *_frag,
797 int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
798 ogg_uint16_t _dc_iquant, const ogg_uint16_t _ac_iquant[64]){
799 ogg_int16_t dct_buf[64];
800 ogg_int16_t res_buf[64];
801 int dst_framei;
802 int dst_ystride;
803 int zzi;
804 int ci;
805 /*_last_zzi is subtly different from an actual count of the number of
806 coefficients we decoded for this block.
807 It contains the value of zzi BEFORE the final token in the block was
808 decoded.
809 In most cases this is an EOB token (the continuation of an EOB run from a
810 previous block counts), and so this is the same as the coefficient count.
811 However, in the case that the last token was NOT an EOB token, but filled
812 the block up with exactly 64 coefficients, _last_zzi will be less than 64.
813 Provided the last token was not a pure zero run, the minimum value it can
814 be is 46, and so that doesn't affect any of the cases in this routine.
815 However, if the last token WAS a pure zero run of length 63, then _last_zzi
816 will be 1 while the number of coefficients decoded is 64.
817 Thus, we will trigger the following special case, where the real
818 coefficient count would not.
819 Note also that a zero run of length 64 will give _last_zzi a value of 0,
820 but we still process the DC coefficient, which might have a non-zero value
821 due to DC prediction.
822 Although convoluted, this is arguably the correct behavior: it allows us to
823 dequantize fewer coefficients and use a smaller transform when the block
824 ends with a long zero run instead of a normal EOB token.
825 It could be smarter... multiple separate zero runs at the end of a block
826 will fool it, but an encoder that generates these really deserves what it
827 gets.
828 Needless to say we inherited this approach from VP3.*/
829 /*Special case only having a DC component.*/
830 if(_last_zzi<2){
831 ogg_int16_t p;
832 /*Why is the iquant product rounded in this case and no others?
833 Who knows.*/
834 p=(ogg_int16_t)((ogg_int32_t)(ogg_int16_t)_frag->dc*_dc_iquant+15>>5);
835 /*LOOP VECTORIZES.*/
836 for(ci=0;ci<64;ci++)res_buf[ci]=p;
838 else{
839 /*First, dequantize the coefficients.*/
840 dct_buf[0]=(ogg_int16_t)((ogg_int32_t)(ogg_int16_t)_frag->dc*_dc_iquant);
841 for(zzi=1;zzi<_ncoefs;zzi++){
842 int ci;
843 ci=OC_FZIG_ZAG[zzi];
844 dct_buf[ci]=(ogg_int16_t)((ogg_int32_t)_dct_coeffs[zzi]*_ac_iquant[ci]);
846 /*Then, fill in the remainder of the coefficients with 0's, and perform
847 the iDCT.*/
848 if(_last_zzi<10){
849 for(;zzi<10;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
850 oc_idct8x8_10_c(res_buf,dct_buf);
852 else{
853 for(;zzi<64;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
854 oc_idct8x8_c(res_buf,dct_buf);
857 /*Fill in the target buffer.*/
858 dst_framei=_state->ref_frame_idx[OC_FRAME_SELF];
859 dst_ystride=_state->ref_frame_bufs[dst_framei][_pli].stride;
860 /*For now ystride values in all ref frames assumed to be equal.*/
861 if(_frag->mbmode==OC_MODE_INTRA){
862 oc_frag_recon_intra(_state,_frag->buffer[dst_framei],dst_ystride,res_buf);
864 else{
865 int ref_framei;
866 int ref_ystride;
867 int mvoffsets[2];
868 ref_framei=_state->ref_frame_idx[OC_FRAME_FOR_MODE[_frag->mbmode]];
869 ref_ystride=_state->ref_frame_bufs[ref_framei][_pli].stride;
870 if(oc_state_get_mv_offsets(_state,mvoffsets,_frag->mv[0],_frag->mv[1],
871 ref_ystride,_pli)>1){
872 oc_frag_recon_inter2(_state,_frag->buffer[dst_framei],dst_ystride,
873 _frag->buffer[ref_framei]+mvoffsets[0],ref_ystride,
874 _frag->buffer[ref_framei]+mvoffsets[1],ref_ystride,res_buf);
876 else{
877 oc_frag_recon_inter(_state,_frag->buffer[dst_framei],dst_ystride,
878 _frag->buffer[ref_framei]+mvoffsets[0],ref_ystride,res_buf);
881 oc_restore_fpu(_state);
884 /*Copies the fragments specified by the lists of fragment indices from one
885 frame to another.
886 _fragis: A pointer to a list of fragment indices.
887 _nfragis: The number of fragment indices to copy.
888 _dst_frame: The reference frame to copy to.
889 _src_frame: The reference frame to copy from.
890 _pli: The color plane the fragments lie in.*/
891 void oc_state_frag_copy(const oc_theora_state *_state,const int *_fragis,
892 int _nfragis,int _dst_frame,int _src_frame,int _pli){
893 _state->opt_vtable.state_frag_copy(_state,_fragis,_nfragis,_dst_frame,
894 _src_frame,_pli);
897 void oc_state_frag_copy_c(const oc_theora_state *_state,const int *_fragis,
898 int _nfragis,int _dst_frame,int _src_frame,int _pli){
899 const int *fragi;
900 const int *fragi_end;
901 int dst_framei;
902 int dst_ystride;
903 int src_framei;
904 int src_ystride;
905 dst_framei=_state->ref_frame_idx[_dst_frame];
906 src_framei=_state->ref_frame_idx[_src_frame];
907 dst_ystride=_state->ref_frame_bufs[dst_framei][_pli].stride;
908 src_ystride=_state->ref_frame_bufs[src_framei][_pli].stride;
909 fragi_end=_fragis+_nfragis;
910 for(fragi=_fragis;fragi<fragi_end;fragi++){
911 oc_fragment *frag;
912 unsigned char *dst;
913 unsigned char *src;
914 int j;
915 frag=_state->frags+*fragi;
916 dst=frag->buffer[dst_framei];
917 src=frag->buffer[src_framei];
918 for(j=0;j<8;j++){
919 memcpy(dst,src,sizeof(dst[0])*8);
920 dst+=dst_ystride;
921 src+=src_ystride;
926 static void loop_filter_h(unsigned char *_pix,int _ystride,int *_bv){
927 int y;
928 _pix-=2;
929 for(y=0;y<8;y++){
930 int f;
931 f=_pix[0]-_pix[3]+3*(_pix[2]-_pix[1]);
932 /*The _bv array is used to compute the function
933 f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0));
934 where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/
935 f=*(_bv+(f+4>>3));
936 _pix[1]=OC_CLAMP255(_pix[1]+f);
937 _pix[2]=OC_CLAMP255(_pix[2]-f);
938 _pix+=_ystride;
942 static void loop_filter_v(unsigned char *_pix,int _ystride,int *_bv){
943 int y;
944 _pix-=_ystride*2;
945 for(y=0;y<8;y++){
946 int f;
947 f=_pix[0]-_pix[_ystride*3]+3*(_pix[_ystride*2]-_pix[_ystride]);
948 /*The _bv array is used to compute the function
949 f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0));
950 where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/
951 f=*(_bv+(f+4>>3));
952 _pix[_ystride]=OC_CLAMP255(_pix[_ystride]+f);
953 _pix[_ystride*2]=OC_CLAMP255(_pix[_ystride*2]-f);
954 _pix++;
958 /*Initialize the bounding values array used by the loop filter.
959 _bv: Storage for the array.
960 Return: 0 on success, or a non-zero value if no filtering need be applied.*/
961 int oc_state_loop_filter_init(oc_theora_state *_state,int *_bv){
962 int flimit;
963 int i;
964 flimit=_state->loop_filter_limits[_state->qis[0]];
965 if(flimit==0)return 1;
966 memset(_bv,0,sizeof(_bv[0])*256);
967 for(i=0;i<flimit;i++){
968 if(127-i-flimit>=0)_bv[127-i-flimit]=i-flimit;
969 _bv[127-i]=-i;
970 _bv[127+i]=i;
971 if(127+i+flimit<256)_bv[127+i+flimit]=flimit-i;
973 return 0;
976 /*Apply the loop filter to a given set of fragment rows in the given plane.
977 The filter may be run on the bottom edge, affecting pixels in the next row of
978 fragments, so this row also needs to be available.
979 _bv: The bounding values array.
980 _refi: The index of the frame buffer to filter.
981 _pli: The color plane to filter.
982 _fragy0: The Y coordinate of the first fragment row to filter.
983 _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/
984 void oc_state_loop_filter_frag_rows(oc_theora_state *_state,int *_bv,
985 int _refi,int _pli,int _fragy0,int _fragy_end){
986 _state->opt_vtable.state_loop_filter_frag_rows(_state,_bv,_refi,_pli,
987 _fragy0,_fragy_end);
990 void oc_state_loop_filter_frag_rows_c(oc_theora_state *_state,int *_bv,
991 int _refi,int _pli,int _fragy0,int _fragy_end){
992 th_img_plane *iplane;
993 oc_fragment_plane *fplane;
994 oc_fragment *frag_top;
995 oc_fragment *frag0;
996 oc_fragment *frag;
997 oc_fragment *frag_end;
998 oc_fragment *frag0_end;
999 oc_fragment *frag_bot;
1000 _bv+=127;
1001 iplane=_state->ref_frame_bufs[_refi]+_pli;
1002 fplane=_state->fplanes+_pli;
1003 /*The following loops are constructed somewhat non-intuitively on purpose.
1004 The main idea is: if a block boundary has at least one coded fragment on
1005 it, the filter is applied to it.
1006 However, the order that the filters are applied in matters, and VP3 chose
1007 the somewhat strange ordering used below.*/
1008 frag_top=_state->frags+fplane->froffset;
1009 frag0=frag_top+_fragy0*fplane->nhfrags;
1010 frag0_end=frag0+(_fragy_end-_fragy0)*fplane->nhfrags;
1011 frag_bot=_state->frags+fplane->froffset+fplane->nfrags;
1012 while(frag0<frag0_end){
1013 frag=frag0;
1014 frag_end=frag+fplane->nhfrags;
1015 while(frag<frag_end){
1016 if(frag->coded){
1017 if(frag>frag0){
1018 loop_filter_h(frag->buffer[_refi],iplane->stride,_bv);
1020 if(frag0>frag_top){
1021 loop_filter_v(frag->buffer[_refi],iplane->stride,_bv);
1023 if(frag+1<frag_end&&!(frag+1)->coded){
1024 loop_filter_h(frag->buffer[_refi]+8,iplane->stride,_bv);
1026 if(frag+fplane->nhfrags<frag_bot&&!(frag+fplane->nhfrags)->coded){
1027 loop_filter_v((frag+fplane->nhfrags)->buffer[_refi],
1028 iplane->stride,_bv);
1031 frag++;
1033 frag0+=fplane->nhfrags;
1037 #if defined(OC_DUMP_IMAGES)
1038 int oc_state_dump_frame(const oc_theora_state *_state,int _frame,
1039 const char *_suf){
1040 /*Dump a PNG of the reconstructed image.*/
1041 png_structp png;
1042 png_infop info;
1043 png_bytep *image;
1044 FILE *fp;
1045 char fname[16];
1046 unsigned char *y_row;
1047 unsigned char *u_row;
1048 unsigned char *v_row;
1049 unsigned char *y;
1050 unsigned char *u;
1051 unsigned char *v;
1052 ogg_int64_t iframe;
1053 ogg_int64_t pframe;
1054 int y_stride;
1055 int u_stride;
1056 int v_stride;
1057 int framei;
1058 int width;
1059 int height;
1060 int imgi;
1061 int imgj;
1062 width=_state->info.frame_width;
1063 height=_state->info.frame_height;
1064 iframe=_state->granpos>>_state->info.keyframe_granule_shift;
1065 pframe=_state->granpos-(iframe<<_state->info.keyframe_granule_shift);
1066 sprintf(fname,"%08i%s.png",(int)(iframe+pframe),_suf);
1067 fp=fopen(fname,"wb");
1068 if(fp==NULL)return TH_EFAULT;
1069 image=(png_bytep *)oc_malloc_2d(height,6*width,sizeof(image[0][0]));
1070 png=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
1071 if(png==NULL){
1072 oc_free_2d(image);
1073 fclose(fp);
1074 return TH_EFAULT;
1076 info=png_create_info_struct(png);
1077 if(info==NULL){
1078 png_destroy_write_struct(&png,NULL);
1079 oc_free_2d(image);
1080 fclose(fp);
1081 return TH_EFAULT;
1083 if(setjmp(png_jmpbuf(png))){
1084 png_destroy_write_struct(&png,&info);
1085 oc_free_2d(image);
1086 fclose(fp);
1087 return TH_EFAULT;
1089 framei=_state->ref_frame_idx[_frame];
1090 y_row=_state->ref_frame_bufs[framei][0].data;
1091 u_row=_state->ref_frame_bufs[framei][1].data;
1092 v_row=_state->ref_frame_bufs[framei][2].data;
1093 y_stride=_state->ref_frame_bufs[framei][0].stride;
1094 u_stride=_state->ref_frame_bufs[framei][1].stride;
1095 v_stride=_state->ref_frame_bufs[framei][2].stride;
1096 /*Chroma up-sampling is just done with a box filter.
1097 This is very likely what will actually be used in practice on a real
1098 display, and also removes one more layer to search in for the source of
1099 artifacts.
1100 As an added bonus, it's dead simple.*/
1101 for(imgi=height;imgi-->0;){
1102 int dc;
1103 y=y_row;
1104 u=u_row;
1105 v=v_row;
1106 for(imgj=0;imgj<6*width;){
1107 float yval;
1108 float uval;
1109 float vval;
1110 unsigned rval;
1111 unsigned gval;
1112 unsigned bval;
1113 /*This is intentionally slow and very accurate.*/
1114 yval=(*y-16)*(1.0F/219);
1115 uval=(*u-128)*(2*(1-0.114F)/224);
1116 vval=(*v-128)*(2*(1-0.299F)/224);
1117 rval=OC_CLAMPI(0,(int)(65535*(yval+vval)+0.5F),65535);
1118 gval=OC_CLAMPI(0,(int)(65535*(
1119 yval-uval*(0.114F/0.587F)-vval*(0.299F/0.587F))+0.5F),65535);
1120 bval=OC_CLAMPI(0,(int)(65535*(yval+uval)+0.5F),65535);
1121 image[imgi][imgj++]=(unsigned char)(rval>>8);
1122 image[imgi][imgj++]=(unsigned char)(rval&0xFF);
1123 image[imgi][imgj++]=(unsigned char)(gval>>8);
1124 image[imgi][imgj++]=(unsigned char)(gval&0xFF);
1125 image[imgi][imgj++]=(unsigned char)(bval>>8);
1126 image[imgi][imgj++]=(unsigned char)(bval&0xFF);
1127 dc=(y-y_row&1)|(_state->info.pixel_fmt&1);
1128 y++;
1129 u+=dc;
1130 v+=dc;
1132 dc=-((height-1-imgi&1)|_state->info.pixel_fmt>>1);
1133 y_row+=y_stride;
1134 u_row+=dc&u_stride;
1135 v_row+=dc&v_stride;
1137 png_init_io(png,fp);
1138 png_set_compression_level(png,Z_BEST_COMPRESSION);
1139 png_set_IHDR(png,info,width,height,16,PNG_COLOR_TYPE_RGB,
1140 PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
1141 switch(_state->info.colorspace){
1142 case TH_CS_ITU_REC_470M:{
1143 png_set_gAMA(png,info,2.2);
1144 png_set_cHRM_fixed(png,info,31006,31616,
1145 67000,32000,21000,71000,14000,8000);
1146 }break;
1147 case TH_CS_ITU_REC_470BG:{
1148 png_set_gAMA(png,info,2.67);
1149 png_set_cHRM_fixed(png,info,31271,32902,
1150 64000,33000,29000,60000,15000,6000);
1151 }break;
1153 png_set_pHYs(png,info,_state->info.aspect_numerator,
1154 _state->info.aspect_denominator,0);
1155 png_set_rows(png,info,image);
1156 png_write_png(png,info,PNG_TRANSFORM_IDENTITY,NULL);
1157 png_write_end(png,info);
1158 png_destroy_write_struct(&png,&info);
1159 oc_free_2d(image);
1160 fclose(fp);
1161 return 0;
1163 #endif
1167 ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos){
1168 oc_theora_state *state;
1169 state=(oc_theora_state *)_encdec;
1170 if(_granpos>=0){
1171 ogg_int64_t iframe;
1172 ogg_int64_t pframe;
1173 iframe=_granpos>>state->info.keyframe_granule_shift;
1174 pframe=_granpos-(iframe<<state->info.keyframe_granule_shift);
1175 /*3.2.0 streams store the frame index in the granule position.
1176 3.2.1 and later store the frame count.
1177 We return the index, so adjust the value if we have a 3.2.1 or later
1178 stream.*/
1179 return iframe+pframe-TH_VERSION_CHECK(&state->info,3,2,1);
1181 return -1;
1184 double th_granule_time(void *_encdec,ogg_int64_t _granpos){
1185 oc_theora_state *state;
1186 state=(oc_theora_state *)_encdec;
1187 if(_granpos>=0){
1188 return (th_granule_frame(_encdec, _granpos)+1)*(
1189 (double)state->info.fps_denominator/state->info.fps_numerator);
1191 return -1;