Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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-2009 *
9 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id: internal.c 17506 2010-10-13 02:52:41Z tterribe $
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <string.h>
21 #include "internal.h"
25 /*A map from the index in the zig zag scan to the coefficient number in a
26 block.
27 All zig zag indices beyond 63 are sent to coefficient 64, so that zero runs
28 past the end of a block in bogus streams get mapped to a known location.*/
29 const unsigned char OC_FZIG_ZAG[128]={
30 0, 1, 8,16, 9, 2, 3,10,
31 17,24,32,25,18,11, 4, 5,
32 12,19,26,33,40,48,41,34,
33 27,20,13, 6, 7,14,21,28,
34 35,42,49,56,57,50,43,36,
35 29,22,15,23,30,37,44,51,
36 58,59,52,45,38,31,39,46,
37 53,60,61,54,47,55,62,63,
38 64,64,64,64,64,64,64,64,
39 64,64,64,64,64,64,64,64,
40 64,64,64,64,64,64,64,64,
41 64,64,64,64,64,64,64,64,
42 64,64,64,64,64,64,64,64,
43 64,64,64,64,64,64,64,64,
44 64,64,64,64,64,64,64,64,
45 64,64,64,64,64,64,64,64
46 };
48 /*A map from the coefficient number in a block to its index in the zig zag
49 scan.*/
50 const unsigned char OC_IZIG_ZAG[64]={
51 0, 1, 5, 6,14,15,27,28,
52 2, 4, 7,13,16,26,29,42,
53 3, 8,12,17,25,30,41,43,
54 9,11,18,24,31,40,44,53,
55 10,19,23,32,39,45,52,54,
56 20,22,33,38,46,51,55,60,
57 21,34,37,47,50,56,59,61,
58 35,36,48,49,57,58,62,63
59 };
61 /*A map from physical macro block ordering to bitstream macro block
62 ordering within a super block.*/
63 const unsigned char OC_MB_MAP[2][2]={{0,3},{1,2}};
65 /*A list of the indices in the oc_mb.map array that can be valid for each of
66 the various chroma decimation types.*/
67 const unsigned char OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]={
68 {0,1,2,3,4,8},
69 {0,1,2,3,4,5,8,9},
70 {0,1,2,3,4,6,8,10},
71 {0,1,2,3,4,5,6,7,8,9,10,11}
72 };
74 /*The number of indices in the oc_mb.map array that can be valid for each of
75 the various chroma decimation types.*/
76 const unsigned char OC_MB_MAP_NIDXS[TH_PF_NFORMATS]={6,8,8,12};
78 /*The number of extra bits that are coded with each of the DCT tokens.
79 Each DCT token has some fixed number of additional bits (possibly 0) stored
80 after the token itself, containing, for example, coefficient magnitude,
81 sign bits, etc.*/
82 const unsigned char OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS]={
83 0,0,0,2,3,4,12,3,6,
84 0,0,0,0,
85 1,1,1,1,2,3,4,5,6,10,
86 1,1,1,1,1,3,4,
87 2,3
88 };
92 int oc_ilog(unsigned _v){
93 int ret;
94 for(ret=0;_v;ret++)_v>>=1;
95 return ret;
96 }
100 void *oc_aligned_malloc(size_t _sz,size_t _align){
101 unsigned char *p;
102 if(_align-1>UCHAR_MAX||(_align&_align-1)||_sz>~(size_t)0-_align)return NULL;
103 p=(unsigned char *)_ogg_malloc(_sz+_align);
104 if(p!=NULL){
105 int offs;
106 offs=((p-(unsigned char *)0)-1&_align-1);
107 p[offs]=offs;
108 p+=offs+1;
109 }
110 return p;
111 }
113 void oc_aligned_free(void *_ptr){
114 unsigned char *p;
115 p=(unsigned char *)_ptr;
116 if(p!=NULL){
117 int offs;
118 offs=*--p;
119 _ogg_free(p-offs);
120 }
121 }
124 void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){
125 size_t rowsz;
126 size_t colsz;
127 size_t datsz;
128 char *ret;
129 colsz=_height*sizeof(void *);
130 rowsz=_sz*_width;
131 datsz=rowsz*_height;
132 /*Alloc array and row pointers.*/
133 ret=(char *)_ogg_malloc(datsz+colsz);
134 if(ret==NULL)return NULL;
135 /*Initialize the array.*/
136 if(ret!=NULL){
137 size_t i;
138 void **p;
139 char *datptr;
140 p=(void **)ret;
141 i=_height;
142 for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
143 }
144 return (void **)ret;
145 }
147 void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz){
148 size_t colsz;
149 size_t rowsz;
150 size_t datsz;
151 char *ret;
152 colsz=_height*sizeof(void *);
153 rowsz=_sz*_width;
154 datsz=rowsz*_height;
155 /*Alloc array and row pointers.*/
156 ret=(char *)_ogg_calloc(datsz+colsz,1);
157 if(ret==NULL)return NULL;
158 /*Initialize the array.*/
159 if(ret!=NULL){
160 size_t i;
161 void **p;
162 char *datptr;
163 p=(void **)ret;
164 i=_height;
165 for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
166 }
167 return (void **)ret;
168 }
170 void oc_free_2d(void *_ptr){
171 _ogg_free(_ptr);
172 }
174 /*Fills in a Y'CbCr buffer with a pointer to the image data in the first
175 buffer, but with the opposite vertical orientation.
176 _dst: The destination buffer.
177 This can be the same as _src.
178 _src: The source buffer.*/
179 void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst,
180 const th_ycbcr_buffer _src){
181 int pli;
182 for(pli=0;pli<3;pli++){
183 _dst[pli].width=_src[pli].width;
184 _dst[pli].height=_src[pli].height;
185 _dst[pli].stride=-_src[pli].stride;
186 _dst[pli].data=_src[pli].data
187 +(1-_dst[pli].height)*(ptrdiff_t)_dst[pli].stride;
188 }
189 }
191 const char *th_version_string(void){
192 return OC_VENDOR_STRING;
193 }
195 ogg_uint32_t th_version_number(void){
196 return (TH_VERSION_MAJOR<<16)+(TH_VERSION_MINOR<<8)+TH_VERSION_SUB;
197 }
199 /*Determines the packet type.
200 Note that this correctly interprets a 0-byte packet as a video data packet.
201 Return: 1 for a header packet, 0 for a data packet.*/
202 int th_packet_isheader(ogg_packet *_op){
203 return _op->bytes>0?_op->packet[0]>>7:0;
204 }
206 /*Determines the frame type of a video data packet.
207 Note that this correctly interprets a 0-byte packet as a delta frame.
208 Return: 1 for a key frame, 0 for a delta frame, and -1 for a header
209 packet.*/
210 int th_packet_iskeyframe(ogg_packet *_op){
211 return _op->bytes<=0?0:_op->packet[0]&0x80?-1:!(_op->packet[0]&0x40);
212 }