Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / media / libtheora / lib / dec / decapiwrapper.c
blob855929cddadc9da44ccae8f7c6478222de1d92c1
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: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <string.h>
20 #include <limits.h>
21 #include "apiwrapper.h"
22 #include "theora/theoradec.h"
24 static void th_dec_api_clear(th_api_wrapper *_api){
25 if(_api->setup)th_setup_free(_api->setup);
26 if(_api->decode)th_decode_free(_api->decode);
27 memset(_api,0,sizeof(*_api));
30 static void theora_decode_clear(theora_state *_td){
31 if(_td->i!=NULL)theora_info_clear(_td->i);
32 #ifdef _TH_DEBUG_
33 fclose(debugout);
34 debugout=NULL;
35 #endif
36 memset(_td,0,sizeof(*_td));
39 static int theora_decode_control(theora_state *_td,int _req,
40 void *_buf,size_t _buf_sz){
41 return th_decode_ctl(((th_api_wrapper *)_td->i->codec_setup)->decode,
42 _req,_buf,_buf_sz);
45 static ogg_int64_t theora_decode_granule_frame(theora_state *_td,
46 ogg_int64_t _gp){
47 return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
50 static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){
51 return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
54 static const oc_state_dispatch_vtbl OC_DEC_DISPATCH_VTBL={
55 (oc_state_clear_func)theora_decode_clear,
56 (oc_state_control_func)theora_decode_control,
57 (oc_state_granule_frame_func)theora_decode_granule_frame,
58 (oc_state_granule_time_func)theora_decode_granule_time,
61 static void th_info2theora_info(theora_info *_ci,const th_info *_info){
62 _ci->version_major=_info->version_major;
63 _ci->version_minor=_info->version_minor;
64 _ci->version_subminor=_info->version_subminor;
65 _ci->width=_info->frame_width;
66 _ci->height=_info->frame_height;
67 _ci->frame_width=_info->pic_width;
68 _ci->frame_height=_info->pic_height;
69 _ci->offset_x=_info->pic_x;
70 _ci->offset_y=_info->pic_y;
71 _ci->fps_numerator=_info->fps_numerator;
72 _ci->fps_denominator=_info->fps_denominator;
73 _ci->aspect_numerator=_info->aspect_numerator;
74 _ci->aspect_denominator=_info->aspect_denominator;
75 switch(_info->colorspace){
76 case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break;
77 case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break;
78 default:_ci->colorspace=OC_CS_UNSPECIFIED;break;
80 switch(_info->pixel_fmt){
81 case TH_PF_420:_ci->pixelformat=OC_PF_420;break;
82 case TH_PF_422:_ci->pixelformat=OC_PF_422;break;
83 case TH_PF_444:_ci->pixelformat=OC_PF_444;break;
84 default:_ci->pixelformat=OC_PF_RSVD;
86 _ci->target_bitrate=_info->target_bitrate;
87 _ci->quality=_info->quality;
88 _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift;
91 int theora_decode_init(theora_state *_td,theora_info *_ci){
92 th_api_info *apiinfo;
93 th_api_wrapper *api;
94 th_info info;
96 api=(th_api_wrapper *)_ci->codec_setup;
97 /*Allocate our own combined API wrapper/theora_info struct.
98 We put them both in one malloc'd block so that when the API wrapper is
99 freed, the info struct goes with it.
100 This avoids having to figure out whether or not we need to free the info
101 struct in either theora_info_clear() or theora_clear().*/
102 apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo));
103 /*Make our own copy of the info struct, since its lifetime should be
104 independent of the one we were passed in.*/
105 *&apiinfo->info=*_ci;
106 /*Convert the info struct now instead of saving the the one we decoded with
107 theora_decode_header(), since the user might have modified values (i.e.,
108 color space, aspect ratio, etc. can be specified from a higher level).
109 The user also might be doing something "clever" with the header packets if
110 they are not using an Ogg encapsulation.*/
111 oc_theora_info2th_info(&info,_ci);
112 /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy
113 of the stuff it needs.*/
114 apiinfo->api.decode=th_decode_alloc(&info,api->setup);
115 if(apiinfo->api.decode==NULL){
116 _ogg_free(apiinfo);
117 return OC_EINVAL;
119 apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear;
120 _td->internal_encode=NULL;
121 /*Provide entry points for ABI compatibility with old decoder shared libs.*/
122 _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL;
123 _td->granulepos=0;
124 _td->i=&apiinfo->info;
125 _td->i->codec_setup=&apiinfo->api;
126 return 0;
129 int theora_decode_header(theora_info *_ci,theora_comment *_cc,ogg_packet *_op){
130 th_api_wrapper *api;
131 th_info info;
132 int ret;
134 #ifdef _TH_DEBUG_
135 debugout = fopen("theoradec-debugout.txt","w");
136 #endif
138 api=(th_api_wrapper *)_ci->codec_setup;
139 /*Allocate an API wrapper struct on demand, since it will not also include a
140 theora_info struct like the ones that are used in a theora_state struct.*/
141 if(api==NULL){
142 _ci->codec_setup=_ogg_calloc(1,sizeof(*api));
143 api=(th_api_wrapper *)_ci->codec_setup;
144 api->clear=(oc_setup_clear_func)th_dec_api_clear;
146 /*Convert from the theora_info struct instead of saving our own th_info
147 struct between calls.
148 The user might be doing something "clever" with the header packets if they
149 are not using an Ogg encapsulation, and we don't want to break this.*/
150 oc_theora_info2th_info(&info,_ci);
151 /*We rely on the fact that theora_comment and th_comment structures are
152 actually identical.
153 Take care not to change this fact unless you change the code here as
154 well!*/
155 ret=th_decode_headerin(&info,(th_comment *)_cc,&api->setup,_op);
156 /*We also rely on the fact that the error return code values are the same,
157 and that the implementations of these two functions return the same set of
158 them.
159 Note that theora_decode_header() really can return OC_NOTFORMAT, even
160 though it is not currently documented to do so.*/
161 if(ret<0)return ret;
162 th_info2theora_info(_ci,&info);
163 return 0;
166 int theora_decode_packetin(theora_state *_td,ogg_packet *_op){
167 th_api_wrapper *api;
168 ogg_int64_t gp;
169 int ret;
171 if(!_td || !_td->i || !_td->i->codec_setup)return OC_FAULT;
172 api=(th_api_wrapper *)_td->i->codec_setup;
173 if(!api || !api->decode)return OC_FAULT;
174 ret=th_decode_packetin(api->decode,_op,&gp);
176 #ifdef _TH_DEBUG_
177 dframe++;
178 #endif
180 if(ret<0)return OC_BADPACKET;
181 _td->granulepos=gp;
182 return 0;
185 int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){
186 th_api_wrapper *api;
187 th_ycbcr_buffer buf;
188 int ret;
190 if(!_td || !_td->i || !_td->i->codec_setup)return OC_FAULT;
191 api=(th_api_wrapper *)_td->i->codec_setup;
192 if(!api || !api->decode)return OC_FAULT;
193 ret=th_decode_ycbcr_out(api->decode,buf);
194 if(ret>=0){
195 _yuv->y_width=buf[0].width;
196 _yuv->y_height=buf[0].height;
197 _yuv->y_stride=buf[0].stride;
198 _yuv->uv_width=buf[1].width;
199 _yuv->uv_height=buf[1].height;
200 _yuv->uv_stride=buf[1].stride;
201 _yuv->y=buf[0].data;
202 _yuv->u=buf[1].data;
203 _yuv->v=buf[2].data;
206 return ret;