summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/yuv2rgb_arm2.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c b/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
index cbd32e8..91cd0b1 100644
--- a/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
+++ b/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
@@ -1,582 +1,583 @@
1/* 1/*
2 * yuv2rgb_arm2.c 2 * yuv2rgb_arm2.c
3 * Copyright (C) 2002 Frederic 'dilb' Boulay. 3 * Copyright (C) 2002 Frederic 'dilb' Boulay.
4 * All Rights Reserved. 4 * All Rights Reserved.
5 * 5 *
6 * Author: Frederic Boulay <dilb@handhelds.org> 6 * Author: Frederic Boulay <dilb@handhelds.org>
7 * 7 *
8 * you can redistribute this file and/or modify 8 * you can redistribute this file and/or modify
9 * it under the terms of the GNU General Public License (version 2) 9 * it under the terms of the GNU General Public License (version 2)
10 * as published by the Free Software Foundation. 10 * as published by the Free Software Foundation.
11 * 11 *
12 * This file is distributed in the hope that it will be useful, 12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 20 *
21 * 21 *
22 * The function defined in this file, are derived from work done in the xine 22 * The function defined in this file, are derived from work done in the xine
23 * project. 23 * project.
24 * In order to improve performance, by strongly reducing memory bandwidth 24 * In order to improve performance, by strongly reducing memory bandwidth
25 * needed, the scaling functions are merged with the yuv2rgb function. 25 * needed, the scaling functions are merged with the yuv2rgb function.
26 */ 26 */
27 27
28#ifdef __arm__ 28#ifdef __arm__
29 29
30#include <stdio.h> 30#include <stdio.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33#include <inttypes.h> 33#include <inttypes.h>
34 34
35#include "yuv2rgb.h" 35#include "yuv2rgb.h"
36#include <xine/xineutils.h> 36#include <xine/xineutils.h>
37 37
38/* Prototypes of the "local" functions available here: */ 38/* Prototypes of the "local" functions available here: */
39/* first prototype, function called when no scaling is needed: */ 39/* first prototype, function called when no scaling is needed: */
40static void arm_rgb16_noscale(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 40static void arm_rgb16_noscale(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
41/* second prototype, function called when no horizontal scaling is needed: */ 41/* second prototype, function called when no horizontal scaling is needed: */
42static void arm_rgb16_step_dx_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 42static void arm_rgb16_step_dx_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
43/* third prototype, function called when scaling is needed for zooming in: */ 43/* third prototype, function called when scaling is needed for zooming in: */
44static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 44static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
45/* fourth prototype, function called when scaling is needed for zooming out (between 1x and 2x): */ 45/* fourth prototype, function called when scaling is needed for zooming out (between 1x and 2x): */
46static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 46static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
47/* fifth prototype, function called when scaling is needed for zooming out (greater than 2x): */ 47/* fifth prototype, function called when scaling is needed for zooming out (greater than 2x): */
48static void arm_rgb16_step_dx_sup_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 48static void arm_rgb16_step_dx_sup_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
49/* sixth prototype, function where the decision of the scaling function to use is made.*/ 49/* sixth prototype, function where the decision of the scaling function to use is made.*/
50static void arm_rgb16_2 (yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 50static void arm_rgb16_2 (yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
51 51
52 52
53 53
54 54
55/* extern function: */ 55/* extern function: */
56 56
57/* Function: */ 57/* Function: */
58void yuv2rgb_init_arm (yuv2rgb_factory_t *this) 58void yuv2rgb_init_arm (yuv2rgb_factory_t *this)
59/* This function initialise the member yuv2rgb_fun, if everything is right 59/* This function initialise the member yuv2rgb_fun, if everything is right
60the function optimised for the arm target should be used.*/ 60the function optimised for the arm target should be used.*/
61 { 61 {
62 if (this->swapped) 62 if (this->swapped)
63 return; /*no swapped pixel output upto now*/ 63 return; /*no swapped pixel output upto now*/
64 64
65 switch (this->mode) 65 switch (this->mode)
66 { 66 {
67 case MODE_16_RGB: 67 case MODE_16_RGB:
68 this->yuv2rgb_fun = arm_rgb16_2; 68 this->yuv2rgb_fun = arm_rgb16_2;
69 break; 69 break;
70 default: 70 default:
71 break;
71 } 72 }
72 } 73 }
73 74
74 75
75 76
76/* local functions: */ 77/* local functions: */
77 78
78/* Function: */ 79/* Function: */
79static void arm_rgb16_2 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 80static void arm_rgb16_2 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
80/* This function takes care of applying the right scaling conversion 81/* This function takes care of applying the right scaling conversion
81(yuv2rgb is included in each scaling function!)*/ 82(yuv2rgb is included in each scaling function!)*/
82 { 83 {
83 if (!this->do_scale) 84 if (!this->do_scale)
84 { 85 {
85 arm_rgb16_noscale(this, _dst, _py, _pu, _pv); 86 arm_rgb16_noscale(this, _dst, _py, _pu, _pv);
86 return; 87 return;
87 } 88 }
88 if (this->step_dx<32768) 89 if (this->step_dx<32768)
89 { 90 {
90 arm_rgb16_step_dx_inf_32768(this, _dst, _py, _pu, _pv); 91 arm_rgb16_step_dx_inf_32768(this, _dst, _py, _pu, _pv);
91 return; 92 return;
92 } 93 }
93 if (this->step_dx==32768) 94 if (this->step_dx==32768)
94 { 95 {
95 arm_rgb16_step_dx_32768(this, _dst, _py, _pu, _pv); 96 arm_rgb16_step_dx_32768(this, _dst, _py, _pu, _pv);
96 return; 97 return;
97 } 98 }
98 if (this->step_dx<65536) 99 if (this->step_dx<65536)
99 { 100 {
100 arm_rgb16_step_dx_bet_32768_65536(this, _dst, _py, _pu, _pv); 101 arm_rgb16_step_dx_bet_32768_65536(this, _dst, _py, _pu, _pv);
101 return; 102 return;
102 } 103 }
103 arm_rgb16_step_dx_sup_65536(this, _dst, _py, _pu, _pv); 104 arm_rgb16_step_dx_sup_65536(this, _dst, _py, _pu, _pv);
104 return; 105 return;
105 } 106 }
106 107
107 108
108/* Function: */ 109/* Function: */
109static void arm_rgb16_noscale(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 110static void arm_rgb16_noscale(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
110/* This function is called when the source and the destination pictures have the same size. 111/* This function is called when the source and the destination pictures have the same size.
111 In this case, scaling part is not needed. 112 In this case, scaling part is not needed.
112 (This code is probably far from being optimised, in particular, the asm 113 (This code is probably far from being optimised, in particular, the asm
113 generated is not the most efficient, a pure asm version will probably 114 generated is not the most efficient, a pure asm version will probably
114 emerge sooner or later). But at least, this version is faster than what 115 emerge sooner or later). But at least, this version is faster than what
115 was used before.*/ 116 was used before.*/
116 { 117 {
117 int height; 118 int height;
118 119
119 height=this->dest_height; 120 height=this->dest_height;
120 121
121 while (height>0) 122 while (height>0)
122 { 123 {
123 uint16_t *r, *g, *b; 124 uint16_t *r, *g, *b;
124 uint8_t *py, *py2, *pu, *pv; 125 uint8_t *py, *py2, *pu, *pv;
125 uint16_t *dst, *dst2; 126 uint16_t *dst, *dst2;
126 int width; 127 int width;
127 register uint8_t p1y, p1u, p1v; 128 register uint8_t p1y, p1u, p1v;
128 129
129 height-=2; 130 height-=2;
130 width=this->dest_width; 131 width=this->dest_width;
131 dst = _dst; 132 dst = _dst;
132 dst2 = _dst + this->rgb_stride; 133 dst2 = _dst + this->rgb_stride;
133 py = _py; 134 py = _py;
134 py2 = _py + this->y_stride; 135 py2 = _py + this->y_stride;
135 pu = _pu; 136 pu = _pu;
136 pv = _pv; 137 pv = _pv;
137 138
138 while (width>0) 139 while (width>0)
139 { 140 {
140 width-=2; 141 width-=2;
141 p1y=*py++; 142 p1y=*py++;
142 p1u=*pu++; 143 p1u=*pu++;
143 p1v=*pv++; 144 p1v=*pv++;
144 145
145 r = this->table_rV[p1v]; 146 r = this->table_rV[p1v];
146 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]); 147 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]);
147 b = this->table_bU[p1u]; 148 b = this->table_bU[p1u];
148 149
149 *dst++ = r[p1y] + g[p1y] + b[p1y]; 150 *dst++ = r[p1y] + g[p1y] + b[p1y];
150 p1y=*py++; 151 p1y=*py++;
151 *dst++ = r[p1y] + g[p1y] + b[p1y]; 152 *dst++ = r[p1y] + g[p1y] + b[p1y];
152 153
153 p1y=*py2++; 154 p1y=*py2++;
154 155
155 *dst2++ = r[p1y] + g[p1y] + b[p1y]; 156 *dst2++ = r[p1y] + g[p1y] + b[p1y];
156 p1y=*py2++; 157 p1y=*py2++;
157 *dst2++ = r[p1y] + g[p1y] + b[p1y]; 158 *dst2++ = r[p1y] + g[p1y] + b[p1y];
158 } 159 }
159 _dst += (this->rgb_stride)<<1; 160 _dst += (this->rgb_stride)<<1;
160 _py += (this->y_stride)<<1; 161 _py += (this->y_stride)<<1;
161 _pu += this->uv_stride; 162 _pu += this->uv_stride;
162 _pv += this->uv_stride; 163 _pv += this->uv_stride;
163 } 164 }
164 } 165 }
165 166
166 167
167/* Function: */ 168/* Function: */
168static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 169static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
169/* This function is called when the destination picture is bigger than the size 170/* This function is called when the destination picture is bigger than the size
170 of the source picture. 171 of the source picture.
171*/ 172*/
172 { 173 {
173 int recal_uv, height; /* Note about recal_uv: bit0 is for 174 int recal_uv, height; /* Note about recal_uv: bit0 is for
174applying scale on u and v, bit1 is for increments of u and v pointers.*/ 175applying scale on u and v, bit1 is for increments of u and v pointers.*/
175 int dy; 176 int dy;
176 177
177 dy = 0; 178 dy = 0;
178 height = this->dest_height; 179 height = this->dest_height;
179 recal_uv=1; // 1 for evaluation of scale_line, needed the first time 180 recal_uv=1; // 1 for evaluation of scale_line, needed the first time
180 181
181 while(1) 182 while(1)
182 { 183 {
183 register int dxy; 184 register int dxy;
184 register int dxuv; 185 register int dxuv;
185 register uint8_t p1y, p2y; 186 register uint8_t p1y, p2y;
186 uint8_t dest1y, dest2y; 187 uint8_t dest1y, dest2y;
187 register uint8_t p1u, p2u; 188 register uint8_t p1u, p2u;
188 register uint8_t p1v, p2v; 189 register uint8_t p1v, p2v;
189 uint8_t dest1u; 190 uint8_t dest1u;
190 uint8_t dest1v; 191 uint8_t dest1v;
191 int width; 192 int width;
192 uint8_t *u_buffer; 193 uint8_t *u_buffer;
193 uint8_t *v_buffer; 194 uint8_t *v_buffer;
194 uint16_t *r, *g, *b; 195 uint16_t *r, *g, *b;
195 uint8_t *py, *pu, *pv; 196 uint8_t *py, *pu, *pv;
196 uint16_t *dst; 197 uint16_t *dst;
197 198
198 dxy = 0; 199 dxy = 0;
199 dxuv = 0; 200 dxuv = 0;
200 width = this->dest_width; 201 width = this->dest_width;
201 u_buffer=this->u_buffer; 202 u_buffer=this->u_buffer;
202 v_buffer=this->v_buffer; 203 v_buffer=this->v_buffer;
203 dst = (uint16_t*)_dst; 204 dst = (uint16_t*)_dst;
204 py = _py; 205 py = _py;
205 pu = _pu; 206 pu = _pu;
206 pv = _pv; 207 pv = _pv;
207 208
208 //proceed with line scaling/conversion 209 //proceed with line scaling/conversion
209 if ((recal_uv&1)!=0) 210 if ((recal_uv&1)!=0)
210 { 211 {
211 recal_uv^=1; //reset bit0. 212 recal_uv^=1; //reset bit0.
212 // init values: 213 // init values:
213 p1u = *pu++; 214 p1u = *pu++;
214 p2u = *pu++; 215 p2u = *pu++;
215 p1v = *pv++; 216 p1v = *pv++;
216 p2v = *pv++; 217 p2v = *pv++;
217 p1y = *py++; 218 p1y = *py++;
218 p2y = *py++; 219 p2y = *py++;
219 220
220 //width loop (compute all data for a line). 221 //width loop (compute all data for a line).
221 while (width>0) 222 while (width>0)
222 { 223 {
223 // proceed with u and v first (ok, and y too finally :)) [scaling part]: 224 // proceed with u and v first (ok, and y too finally :)) [scaling part]:
224 // evaluate 1u, 1v, and 2y 225 // evaluate 1u, 1v, and 2y
225 //block1_uvy 226 //block1_uvy
226 dest1u=p1u + ((dxuv*(p2u-p1u))>>15); 227 dest1u=p1u + ((dxuv*(p2u-p1u))>>15);
227 dest1v=p1v + ((dxuv*(p2v-p1v))>>15); 228 dest1v=p1v + ((dxuv*(p2v-p1v))>>15);
228 // as u and v are evaluated, better save them now 229 // as u and v are evaluated, better save them now
229 *u_buffer++ = (uint8_t)dest1u; 230 *u_buffer++ = (uint8_t)dest1u;
230 *v_buffer++ = (uint8_t)dest1v; 231 *v_buffer++ = (uint8_t)dest1v;
231 232
232 dest1y=p1y + ((dxy*(p2y-p1y))>>15); 233 dest1y=p1y + ((dxy*(p2y-p1y))>>15);
233 234
234 dxuv += this->step_dx; 235 dxuv += this->step_dx;
235 dxy += this->step_dx; 236 dxy += this->step_dx;
236 if (dxuv > 32768) 237 if (dxuv > 32768)
237 { 238 {
238 dxuv -= 32768; 239 dxuv -= 32768;
239 p1u = p2u; 240 p1u = p2u;
240 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!! 241 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!!
241 p1v = p2v; 242 p1v = p2v;
242 p2v = *pv++; 243 p2v = *pv++;
243 } 244 }
244 if (dxy > 32768) 245 if (dxy > 32768)
245 { 246 {
246 dxy -= 32768; 247 dxy -= 32768;
247 p1y = p2y; 248 p1y = p2y;
248 p2y = *py++; 249 p2y = *py++;
249 } 250 }
250 //end block1_uvy 251 //end block1_uvy
251 252
252 //block2_y 253 //block2_y
253 dest2y=p1y + ((dxy*(p2y-p1y))>>15); 254 dest2y=p1y + ((dxy*(p2y-p1y))>>15);
254 255
255 dxy += this->step_dx; 256 dxy += this->step_dx;
256 if (dxy > 32768) 257 if (dxy > 32768)
257 { 258 {
258 dxy -= 32768; 259 dxy -= 32768;
259 p1y = p2y; 260 p1y = p2y;
260 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!! 261 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!!
261 } 262 }
262 //end block2_y 263 //end block2_y
263 264
264 // proceed now with YUV2RGB [conversion part]: 265 // proceed now with YUV2RGB [conversion part]:
265 // u and v are currently in dest1u and dest1v 266 // u and v are currently in dest1u and dest1v
266 // the 2 y are in dest1y and dest2y. 267 // the 2 y are in dest1y and dest2y.
267 // RGB(0),DST1(0), RGB(1), DST1(1) 268 // RGB(0),DST1(0), RGB(1), DST1(1)
268 r = this->table_rV[dest1v]; 269 r = this->table_rV[dest1v];
269 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]); 270 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]);
270 b = this->table_bU[dest1u]; 271 b = this->table_bU[dest1u];
271 272
272 *dst++ = r[dest1y] + g[dest1y] + b[dest1y]; 273 *dst++ = r[dest1y] + g[dest1y] + b[dest1y];
273 *dst++ = r[dest2y] + g[dest2y] + b[dest2y]; 274 *dst++ = r[dest2y] + g[dest2y] + b[dest2y];
274 275
275 width -=2; 276 width -=2;
276 } 277 }
277 } 278 }
278 else 279 else
279 { 280 {
280 // this case is simple, u and v are already evaluated, 281 // this case is simple, u and v are already evaluated,
281 // Note pour moi: r, g et b pourraient etre reutilises!! 282 // Note pour moi: r, g et b pourraient etre reutilises!!
282 283
283 // init values: 284 // init values:
284 p1y = *py++; 285 p1y = *py++;
285 p2y = *py++; 286 p2y = *py++;
286 287
287 //width loop (compute all data for a line). 288 //width loop (compute all data for a line).
288 while (width>0) 289 while (width>0)
289 { 290 {
290 // proceed with y [scaling part]: 291 // proceed with y [scaling part]:
291 // evaluate 2y 292 // evaluate 2y
292 //block1_y 293 //block1_y
293 dest1y=p1y + ((dxy*(p2y-p1y))>>15); 294 dest1y=p1y + ((dxy*(p2y-p1y))>>15);
294 295
295 dxy += this->step_dx; 296 dxy += this->step_dx;
296 if (dxy > 32768) 297 if (dxy > 32768)
297 { 298 {
298 dxy -= 32768; 299 dxy -= 32768;
299 p1y = p2y; 300 p1y = p2y;
300 p2y = *py++; 301 p2y = *py++;
301 } 302 }
302 //end block1_uvy 303 //end block1_uvy
303 304
304 //block2_y 305 //block2_y
305 dest2y=p1y + ((dxy*(p2y-p1y))>>15); 306 dest2y=p1y + ((dxy*(p2y-p1y))>>15);
306 307
307 dxy += this->step_dx; 308 dxy += this->step_dx;
308 if (dxy > 32768) 309 if (dxy > 32768)
309 { 310 {
310 dxy -= 32768; 311 dxy -= 32768;
311 p1y = p2y; 312 p1y = p2y;
312 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!! 313 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!!
313 } 314 }
314 //end block2_y 315 //end block2_y
315 316
316 // proceed now with YUV2RGB [conversion part]: 317 // proceed now with YUV2RGB [conversion part]:
317 // u and v are currently in dest1u and dest1v 318 // u and v are currently in dest1u and dest1v
318 // the 2 y are in dest1y and dest2y. 319 // the 2 y are in dest1y and dest2y.
319 // RGB(0),DST1(0) 320 // RGB(0),DST1(0)
320 dest1u=*u_buffer++; 321 dest1u=*u_buffer++;
321 dest1v=*v_buffer++; 322 dest1v=*v_buffer++;
322 r = this->table_rV[dest1v]; 323 r = this->table_rV[dest1v];
323 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]); 324 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]);
324 b = this->table_bU[dest1u]; 325 b = this->table_bU[dest1u];
325 326
326 *dst++ = r[dest1y] + g[dest1y] + b[dest1y]; 327 *dst++ = r[dest1y] + g[dest1y] + b[dest1y];
327 *dst++ = r[dest2y] + g[dest2y] + b[dest2y]; 328 *dst++ = r[dest2y] + g[dest2y] + b[dest2y];
328 329
329 width -=2; 330 width -=2;
330 } 331 }
331 } 332 }
332 // end of line scaling/conversion 333 // end of line scaling/conversion
333 dy += this->step_dy; 334 dy += this->step_dy;
334 _dst += this->rgb_stride; 335 _dst += this->rgb_stride;
335 336
336 while (--height > 0 && dy < 32768) 337 while (--height > 0 && dy < 32768)
337 { 338 {
338 xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); // *2 because of int8 cast! 339 xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); // *2 because of int8 cast!
339 dy += this->step_dy; 340 dy += this->step_dy;
340 _dst += this->rgb_stride; 341 _dst += this->rgb_stride;
341 } 342 }
342 343
343 344
344 if (height <= 0) 345 if (height <= 0)
345 break; 346 break;
346 347
347 do 348 do
348 { 349 {
349 dy -= 32768; 350 dy -= 32768;
350 _py += this->y_stride; 351 _py += this->y_stride;
351 352
352 recal_uv^=2; /*bit 0 for reevaluation of scanline, bit 1 for offset.*/ 353 recal_uv^=2; /*bit 0 for reevaluation of scanline, bit 1 for offset.*/
353 354
354 if ((recal_uv&2)==0) 355 if ((recal_uv&2)==0)
355 { 356 {
356 _pu += this->uv_stride; 357 _pu += this->uv_stride;
357 _pv += this->uv_stride; 358 _pv += this->uv_stride;
358 recal_uv|=1; // if update, then reevaluate scanline! 359 recal_uv|=1; // if update, then reevaluate scanline!
359 } 360 }
360 } 361 }
361 while( dy>=32768); 362 while( dy>=32768);
362 } 363 }
363 } 364 }
364 365
365 366
366 367
367/* Function: */ 368/* Function: */
368static void arm_rgb16_step_dx_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 369static void arm_rgb16_step_dx_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
369/* This function is called when the widht of the destination picture is the 370/* This function is called when the widht of the destination picture is the
370 same as the size of the source picture. 371 same as the size of the source picture.
371*/ 372*/
372 { 373 {
373 int recal_uv, height; 374 int recal_uv, height;
374 int dy; 375 int dy;
375 376
376 dy = 0; 377 dy = 0;
377 height=this->dest_height; 378 height=this->dest_height;
378 recal_uv=0; 379 recal_uv=0;
379 380
380 while (1) 381 while (1)
381 { 382 {
382 uint16_t *r, *g, *b; 383 uint16_t *r, *g, *b;
383 uint8_t *py, *pu, *pv; 384 uint8_t *py, *pu, *pv;
384 uint16_t *dst; 385 uint16_t *dst;
385 int width; 386 int width;
386 register uint8_t p1y, p1u, p1v; 387 register uint8_t p1y, p1u, p1v;
387 388
388 width=this->dest_width; 389 width=this->dest_width;
389 dst = (uint16_t*)_dst; 390 dst = (uint16_t*)_dst;
390 py = _py; 391 py = _py;
391 pu = _pu; 392 pu = _pu;
392 pv = _pv; 393 pv = _pv;
393 394
394 while (width>0) 395 while (width>0)
395 { 396 {
396 width-=2; 397 width-=2;
397 p1y=*py++; 398 p1y=*py++;
398 p1u=*pu++; 399 p1u=*pu++;
399 p1v=*pv++; 400 p1v=*pv++;
400 401
401 r = this->table_rV[p1v]; 402 r = this->table_rV[p1v];
402 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]); 403 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]);
403 b = this->table_bU[p1u]; 404 b = this->table_bU[p1u];
404 405
405 *dst++ = r[p1y] + g[p1y] + b[p1y]; 406 *dst++ = r[p1y] + g[p1y] + b[p1y];
406 p1y=*py++; 407 p1y=*py++;
407 *dst++ = r[p1y] + g[p1y] + b[p1y]; 408 *dst++ = r[p1y] + g[p1y] + b[p1y];
408 } 409 }
409 410
410 411
411 412
412 // end of line scaling/conversion 413 // end of line scaling/conversion
413 dy += this->step_dy; 414 dy += this->step_dy;
414 _dst += this->rgb_stride; 415 _dst += this->rgb_stride;
415 416
416 while (--height > 0 && dy < 32768) 417 while (--height > 0 && dy < 32768)
417 { 418 {
418 xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); // *2 because of int8 cast! 419 xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); // *2 because of int8 cast!
419 dy += this->step_dy; 420 dy += this->step_dy;
420 _dst += this->rgb_stride; 421 _dst += this->rgb_stride;
421 } 422 }
422 423
423 424
424 if (height <= 0) 425 if (height <= 0)
425 break; 426 break;
426 427
427 do 428 do
428 { 429 {
429 dy -= 32768; 430 dy -= 32768;
430 _py += this->y_stride; 431 _py += this->y_stride;
431 432
432 recal_uv^=2; /*bit 0 for reevaluation of scanline, bit 1 for offset.*/ 433 recal_uv^=2; /*bit 0 for reevaluation of scanline, bit 1 for offset.*/
433 434
434 if ((recal_uv&2)==0) 435 if ((recal_uv&2)==0)
435 { 436 {
436 _pu += this->uv_stride; 437 _pu += this->uv_stride;
437 _pv += this->uv_stride; 438 _pv += this->uv_stride;
438 recal_uv|=1; // if update, then reevaluate scanline! 439 recal_uv|=1; // if update, then reevaluate scanline!
439 } 440 }
440 } 441 }
441 while( dy>=32768); 442 while( dy>=32768);
442 } 443 }
443 } 444 }
444 445
445 446
446 447
447/* Function: */ 448/* Function: */
448static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 449static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
449/* This function is called when the destination picture is between the size 450/* This function is called when the destination picture is between the size
450 of the source picture, and half its size. 451 of the source picture, and half its size.
451*/ 452*/
452 { 453 {
453 int recal_uv, height; /* Note about recal_uv: bit0 is for 454 int recal_uv, height; /* Note about recal_uv: bit0 is for
454applying scale on u and v, bit1 is for increments of u and v pointers.*/ 455applying scale on u and v, bit1 is for increments of u and v pointers.*/
455 int dy; 456 int dy;
456 457
457 dy = 0; 458 dy = 0;
458 height = this->dest_height; 459 height = this->dest_height;
459 recal_uv=1; // 1 for evaluation of scale_line, needed the first time 460 recal_uv=1; // 1 for evaluation of scale_line, needed the first time
460 461
461 while(1) 462 while(1)
462 { 463 {
463 register int dxy; 464 register int dxy;
464 register int dxuv; 465 register int dxuv;
465 register uint8_t p1y, p2y; 466 register uint8_t p1y, p2y;
466 uint8_t dest1y, dest2y; 467 uint8_t dest1y, dest2y;
467 register uint8_t p1u, p2u; 468 register uint8_t p1u, p2u;
468 register uint8_t p1v, p2v; 469 register uint8_t p1v, p2v;
469 uint8_t dest1u; 470 uint8_t dest1u;
470 uint8_t dest1v; 471 uint8_t dest1v;
471 int width; 472 int width;
472 uint8_t *u_buffer; 473 uint8_t *u_buffer;
473 uint8_t *v_buffer; 474 uint8_t *v_buffer;
474 uint16_t *r, *g, *b; 475 uint16_t *r, *g, *b;
475 uint8_t *py, *pu, *pv; 476 uint8_t *py, *pu, *pv;
476 uint16_t *dst; 477 uint16_t *dst;
477 478
478 dxy = 0; 479 dxy = 0;
479 dxuv = 0; 480 dxuv = 0;
480 width = this->dest_width; 481 width = this->dest_width;
481 u_buffer=this->u_buffer; 482 u_buffer=this->u_buffer;
482 v_buffer=this->v_buffer; 483 v_buffer=this->v_buffer;
483 dst = (uint16_t*)_dst; 484 dst = (uint16_t*)_dst;
484 py = _py; 485 py = _py;
485 pu = _pu; 486 pu = _pu;
486 pv = _pv; 487 pv = _pv;
487 488
488 //proceed with line scaling/conversion 489 //proceed with line scaling/conversion
489 if ((recal_uv&1)!=0) 490 if ((recal_uv&1)!=0)
490 { 491 {
491 recal_uv^=1; //reset bit0. 492 recal_uv^=1; //reset bit0.
492 // init values: 493 // init values:
493 p1u = *pu++; 494 p1u = *pu++;
494 p2u = *pu++; 495 p2u = *pu++;
495 p1v = *pv++; 496 p1v = *pv++;
496 p2v = *pv++; 497 p2v = *pv++;
497 p1y = *py++; 498 p1y = *py++;
498 p2y = *py++; 499 p2y = *py++;
499 500
500 //width loop (compute all data for a line). 501 //width loop (compute all data for a line).
501 while (width>0) 502 while (width>0)
502 { 503 {
503 // proceed with u and v first (ok, and y too finally :)) [scaling part]: 504 // proceed with u and v first (ok, and y too finally :)) [scaling part]:
504 // evaluate 1u, 1v, and 2y 505 // evaluate 1u, 1v, and 2y
505 //block1_uvy 506 //block1_uvy
506 dest1u=p1u + ((dxuv*(p2u-p1u))>>15); 507 dest1u=p1u + ((dxuv*(p2u-p1u))>>15);
507 dest1v=p1v + ((dxuv*(p2v-p1v))>>15); 508 dest1v=p1v + ((dxuv*(p2v-p1v))>>15);
508 // as u and v are evaluated, better save them now 509 // as u and v are evaluated, better save them now
509 *u_buffer++ = (uint8_t)dest1u; 510 *u_buffer++ = (uint8_t)dest1u;
510 *v_buffer++ = (uint8_t)dest1v; 511 *v_buffer++ = (uint8_t)dest1v;
511 512
512 dest1y=p1y + ((dxy*(p2y-p1y))>>15); 513 dest1y=p1y + ((dxy*(p2y-p1y))>>15);
513 514
514 dxuv += this->step_dx; 515 dxuv += this->step_dx;
515 dxy += this->step_dx; 516 dxy += this->step_dx;
516 if (dxuv > 65536) 517 if (dxuv > 65536)
517 { 518 {
518 dxuv -= 65536; 519 dxuv -= 65536;
519 p1u = *pu++; 520 p1u = *pu++;
520 p2u = *pu++; 521 p2u = *pu++;
521 p1v = *pv++; 522 p1v = *pv++;
522 p2v = *pv++; 523 p2v = *pv++;
523 } 524 }
524 else 525 else
525 { 526 {
526 dxuv -= 32768; 527 dxuv -= 32768;
527 p1u = p2u; 528 p1u = p2u;
528 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!! 529 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!!
529 p1v = p2v; 530 p1v = p2v;
530 p2v = *pv++; 531 p2v = *pv++;
531 } 532 }
532 if (dxy > 65536) 533 if (dxy > 65536)
533 { 534 {
534 dxy -= 65536; 535 dxy -= 65536;
535 p1y = *py++; 536 p1y = *py++;
536 p2y = *py++; 537 p2y = *py++;
537 } 538 }
538 else 539 else
539 { 540 {
540 dxy -= 32768; 541 dxy -= 32768;
541 p1y = p2y; 542 p1y = p2y;
542 p2y = *py++; 543 p2y = *py++;
543 } 544 }
544 //end block1_uvy 545 //end block1_uvy
545 546
546 //block2_y 547 //block2_y
547 dest2y=p1y + ((dxy*(p2y-p1y))>>15); 548 dest2y=p1y + ((dxy*(p2y-p1y))>>15);
548 549
549 dxy += this->step_dx; 550 dxy += this->step_dx;
550 if (dxy > 65536) 551 if (dxy > 65536)
551 { 552 {
552 dxy -= 65536; 553 dxy -= 65536;
553 p1y = *py++; 554 p1y = *py++;
554 p2y = *py++; 555 p2y = *py++;
555 } 556 }
556 else 557 else
557 { 558 {
558 dxy -= 32768; 559 dxy -= 32768;
559 p1y = p2y; 560 p1y = p2y;
560 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!! 561 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!!
561 } 562 }
562 //end block2_y 563 //end block2_y
563 564
564 // proceed now with YUV2RGB [conversion part]: 565 // proceed now with YUV2RGB [conversion part]:
565 // u and v are currently in dest1u and dest1v 566 // u and v are currently in dest1u and dest1v
566 // the 2 y are in dest1y and dest2y. 567 // the 2 y are in dest1y and dest2y.
567 // RGB(0),DST1(0), RGB(1), DST1(1) 568 // RGB(0),DST1(0), RGB(1), DST1(1)
568 r = this->table_rV[dest1v]; 569 r = this->table_rV[dest1v];
569 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]); 570 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]);
570 b = this->table_bU[dest1u]; 571 b = this->table_bU[dest1u];
571 572
572 *dst++ = r[dest1y] + g[dest1y] + b[dest1y]; 573 *dst++ = r[dest1y] + g[dest1y] + b[dest1y];
573 *dst++ = r[dest2y] + g[dest2y] + b[dest2y]; 574 *dst++ = r[dest2y] + g[dest2y] + b[dest2y];
574 575
575 width -=2; 576 width -=2;
576 } 577 }
577 } 578 }
578 else 579 else
579 { 580 {
580 // this case is simple, u and v are already evaluated, 581 // this case is simple, u and v are already evaluated,
581 // Note pour moi: r, g et b pourraient etre reutilises!! 582 // Note pour moi: r, g et b pourraient etre reutilises!!
582 583