1
2
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6
7 #include <schroedinger/schro.h>
8 #include <schroedinger/schroframe.h>
9 #include <schroedinger/schrogpuframe.h>
10 #include <schroedinger/opengl/schroopenglframe.h>
11 #include <schroedinger/schrovirtframe.h>
12 #include <schroedinger/schroorc.h>
13
14 #include <orc/orc.h>
15
16 #include <stdlib.h>
17 #include <string.h>
18
19
20 static SchroMutex *frame_mutex;
21
22 /**
23 * schro_frame_new:
24 *
25 * Creates a new SchroFrame object. The created frame is uninitialized
26 * and has no data storage associated with it. The caller must fill
27 * in the required information.
28 *
29 * Returns: a new SchroFrame object
30 */
31 SchroFrame *
schro_frame_new(void)32 schro_frame_new (void)
33 {
34 SchroFrame *frame;
35
36 if (frame_mutex == NULL) {
37 frame_mutex = schro_mutex_new ();
38 }
39
40 frame = schro_malloc0 (sizeof (*frame));
41 frame->refcount = 1;
42
43 return frame;
44 }
45
46 /**
47 * schro_frame_new_and_alloc:
48 *
49 * Creates a new SchroFrame object with the requested size and format.
50 *
51 * Returns: a new SchroFrame object
52 */
53 SchroFrame *
schro_frame_new_and_alloc(SchroMemoryDomain * domain,SchroFrameFormat format,int width,int height)54 schro_frame_new_and_alloc (SchroMemoryDomain * domain, SchroFrameFormat format,
55 int width, int height)
56 {
57 return schro_frame_new_and_alloc_full (domain, format, width, height, 0, FALSE);
58 }
59
60 SchroFrame *
schro_frame_new_and_alloc_full(SchroMemoryDomain * domain,SchroFrameFormat format,int width,int height,int extension,int upsampled)61 schro_frame_new_and_alloc_full (SchroMemoryDomain * domain,
62 SchroFrameFormat format, int width, int height, int extension,
63 int upsampled)
64 {
65 SchroFrame *frame = schro_frame_new ();
66 int bytes_pp;
67 int h_shift, v_shift;
68 int chroma_width;
69 int chroma_height;
70
71 SCHRO_ASSERT (width > 0);
72 SCHRO_ASSERT (height > 0);
73
74 frame->format = format;
75 frame->width = width;
76 frame->height = height;
77 frame->domain = domain;
78 frame->extension = extension;
79 frame->is_upsampled = upsampled;
80
81 if (SCHRO_FRAME_IS_PACKED (format)) {
82 SCHRO_ASSERT (extension == 0);
83
84 frame->components[0].format = format;
85 frame->components[0].width = width;
86 frame->components[0].height = height;
87 if (format == SCHRO_FRAME_FORMAT_AYUV) {
88 frame->components[0].stride = width * 4;
89 } else {
90 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
91 }
92 frame->components[0].length = frame->components[0].stride * height;
93
94 if (domain) {
95 frame->regions[0] = schro_memory_domain_alloc (domain,
96 frame->components[0].length);
97 } else {
98 frame->regions[0] = schro_malloc (frame->components[0].length);
99 }
100
101 frame->components[0].data = frame->regions[0];
102 frame->components[0].v_shift = 0;
103 frame->components[0].h_shift = 0;
104
105 return frame;
106 }
107
108 switch (SCHRO_FRAME_FORMAT_DEPTH (format)) {
109 case SCHRO_FRAME_FORMAT_DEPTH_U8:
110 bytes_pp = 1;
111 break;
112 case SCHRO_FRAME_FORMAT_DEPTH_S16:
113 bytes_pp = 2;
114 break;
115 case SCHRO_FRAME_FORMAT_DEPTH_S32:
116 bytes_pp = 4;
117 break;
118 default:
119 SCHRO_ASSERT (0);
120 bytes_pp = 0;
121 break;
122 }
123
124 h_shift = SCHRO_FRAME_FORMAT_H_SHIFT (format);
125 v_shift = SCHRO_FRAME_FORMAT_V_SHIFT (format);
126 chroma_width = ROUND_UP_SHIFT (width, h_shift);
127 chroma_height = ROUND_UP_SHIFT (height, v_shift);
128
129 frame->components[0].format = format;
130 frame->components[0].width = width;
131 frame->components[0].height = height;
132 frame->components[0].stride =
133 ROUND_UP_16 ((width + extension * 2) * bytes_pp);
134 if (upsampled) {
135 frame->components[0].stride *= 4;
136 }
137 frame->components[0].length =
138 frame->components[0].stride * (frame->components[0].height +
139 extension * 2);
140 frame->components[0].v_shift = 0;
141 frame->components[0].h_shift = 0;
142
143 frame->components[1].format = format;
144 frame->components[1].width = chroma_width;
145 frame->components[1].height = chroma_height;
146 frame->components[1].stride =
147 ROUND_UP_16 ((chroma_width + extension * 2) * bytes_pp);
148 if (upsampled) {
149 frame->components[1].stride *= 4;
150 }
151 frame->components[1].length =
152 frame->components[1].stride * (frame->components[1].height +
153 extension * 2);
154 frame->components[1].v_shift = v_shift;
155 frame->components[1].h_shift = h_shift;
156
157 frame->components[2].format = format;
158 frame->components[2].width = chroma_width;
159 frame->components[2].height = chroma_height;
160 frame->components[2].stride =
161 ROUND_UP_16 ((chroma_width + extension * 2) * bytes_pp);
162 if (upsampled) {
163 frame->components[2].stride *= 4;
164 }
165 frame->components[2].length =
166 frame->components[2].stride * (frame->components[2].height +
167 extension * 2);
168 frame->components[2].v_shift = v_shift;
169 frame->components[2].h_shift = h_shift;
170
171 if (domain) {
172 frame->regions[0] = schro_memory_domain_alloc (domain,
173 frame->components[0].length +
174 frame->components[1].length + frame->components[2].length);
175 } else {
176 frame->regions[0] = malloc (frame->components[0].length +
177 frame->components[1].length + frame->components[2].length);
178 }
179
180 frame->components[0].data = SCHRO_OFFSET (frame->regions[0],
181 frame->components[0].stride * extension + bytes_pp * extension);
182 frame->components[1].data = SCHRO_OFFSET (frame->regions[0],
183 frame->components[0].length +
184 frame->components[1].stride * extension + bytes_pp * extension);
185 frame->components[2].data = SCHRO_OFFSET (frame->regions[0],
186 frame->components[0].length + frame->components[1].length +
187 frame->components[2].stride * extension + bytes_pp * extension);
188
189 return frame;
190 }
191
192 SchroFrame *
schro_frame_new_and_alloc_extended(SchroMemoryDomain * domain,SchroFrameFormat format,int width,int height,int extension)193 schro_frame_new_and_alloc_extended (SchroMemoryDomain * domain,
194 SchroFrameFormat format, int width, int height, int extension)
195 {
196 return schro_frame_new_and_alloc_full (domain, format, width,
197 height, extension, FALSE);
198 }
199
200 /**
201 * schro_frame_new_from_data_YUY2:
202 *
203 * Creates a new SchroFrame object with the requested size using
204 * the data pointed to by @data. The data must be in YUY2 format.
205 * The data must remain for the lifetime of the SchroFrame object.
206 * It is recommended to use schro_frame_set_free_callback() for
207 * notification when the data is no longer needed.
208 *
209 * Returns: a new SchroFrame object
210 */
211 SchroFrame *
schro_frame_new_from_data_YUY2(void * data,int width,int height)212 schro_frame_new_from_data_YUY2 (void *data, int width, int height)
213 {
214 SchroFrame *frame = schro_frame_new ();
215
216 frame->format = SCHRO_FRAME_FORMAT_YUYV;
217
218 frame->width = width;
219 frame->height = height;
220
221 frame->components[0].format = frame->format;
222 frame->components[0].width = width;
223 frame->components[0].height = height;
224 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
225 frame->components[0].data = data;
226 frame->components[0].length = frame->components[0].stride * height;
227 frame->components[0].v_shift = 0;
228 frame->components[0].h_shift = 0;
229
230 return frame;
231 }
232
233 /**
234 * schro_frame_new_from_data_UYVY:
235 *
236 * Creates a new SchroFrame object with the requested size using
237 * the data pointed to by @data. The data must be in UYVY format.
238 * The data must remain for the lifetime of the SchroFrame object.
239 * It is recommended to use schro_frame_set_free_callback() for
240 * notification when the data is no longer needed.
241 *
242 * Returns: a new SchroFrame object
243 */
244 SchroFrame *
schro_frame_new_from_data_UYVY(void * data,int width,int height)245 schro_frame_new_from_data_UYVY (void *data, int width, int height)
246 {
247 SchroFrame *frame = schro_frame_new ();
248
249 frame->format = SCHRO_FRAME_FORMAT_UYVY;
250
251 frame->width = width;
252 frame->height = height;
253
254 frame->components[0].format = frame->format;
255 frame->components[0].width = width;
256 frame->components[0].height = height;
257 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
258 frame->components[0].data = data;
259 frame->components[0].length = frame->components[0].stride * height;
260 frame->components[0].v_shift = 0;
261 frame->components[0].h_shift = 0;
262
263 return frame;
264 }
265
266 /**
267 * schro_frame_new_from_data_UYVY_full:
268 *
269 * Creates a new SchroFrame object with the requested size using
270 * the data pointed to by @data. The data must be in UYVY format,
271 * although the row stride is allowed to be different than what
272 * would normally be calculated from @width.
273 * The data must remain for the lifetime of the SchroFrame object.
274 * It is recommended to use schro_frame_set_free_callback() for
275 * notification when the data is no longer needed.
276 *
277 * Returns: a new SchroFrame object
278 */
279 SchroFrame *
schro_frame_new_from_data_UYVY_full(void * data,int width,int height,int stride)280 schro_frame_new_from_data_UYVY_full (void *data, int width, int height,
281 int stride)
282 {
283 SchroFrame *frame = schro_frame_new ();
284
285 frame->format = SCHRO_FRAME_FORMAT_UYVY;
286
287 frame->width = width;
288 frame->height = height;
289
290 frame->components[0].width = width;
291 frame->components[0].height = height;
292 frame->components[0].stride = stride;
293 frame->components[0].data = data;
294 frame->components[0].length = frame->components[0].stride * height;
295 frame->components[0].v_shift = 0;
296 frame->components[0].h_shift = 0;
297
298 return frame;
299 }
300
301 /**
302 * schro_frame_new_from_data_AYUV:
303 *
304 * Creates a new SchroFrame object with the requested size using
305 * the data pointed to by @data. The data must be in AYUV format.
306 * The data must remain for the lifetime of the SchroFrame object.
307 * It is recommended to use schro_frame_set_free_callback() for
308 * notification when the data is no longer needed.
309 *
310 * Returns: a new SchroFrame object
311 */
312 SchroFrame *
schro_frame_new_from_data_AYUV(void * data,int width,int height)313 schro_frame_new_from_data_AYUV (void *data, int width, int height)
314 {
315 SchroFrame *frame = schro_frame_new ();
316
317 frame->format = SCHRO_FRAME_FORMAT_AYUV;
318
319 frame->width = width;
320 frame->height = height;
321
322 frame->components[0].format = frame->format;
323 frame->components[0].width = width;
324 frame->components[0].height = height;
325 frame->components[0].stride = width * 4;
326 frame->components[0].data = data;
327 frame->components[0].length = frame->components[0].stride * height;
328 frame->components[0].v_shift = 0;
329 frame->components[0].h_shift = 0;
330
331 return frame;
332 }
333
334 /**
335 * schro_frame_new_from_data_AY64:
336 *
337 * Creates a new SchroFrame object with the requested size using
338 * the data pointed to by @data. The data must be in AY64 format.
339 * The data must remain for the lifetime of the SchroFrame object.
340 * It is recommended to use schro_frame_set_free_callback() for
341 * notification when the data is no longer needed.
342 *
343 * Returns: a new SchroFrame object
344 */
345 SchroFrame *
schro_frame_new_from_data_AY64(void * data,int width,int height)346 schro_frame_new_from_data_AY64 (void *data, int width, int height)
347 {
348 SchroFrame *frame = schro_frame_new ();
349
350 frame->format = SCHRO_FRAME_FORMAT_AY64;
351
352 frame->width = width;
353 frame->height = height;
354
355 frame->components[0].format = frame->format;
356 frame->components[0].width = width;
357 frame->components[0].height = height;
358 frame->components[0].stride = width * 8;
359 frame->components[0].data = data;
360 frame->components[0].length = frame->components[0].stride * height;
361 frame->components[0].v_shift = 0;
362 frame->components[0].h_shift = 0;
363
364 return frame;
365 }
366
367 /**
368 * schro_frame_new_from_data_v216:
369 *
370 * Creates a new SchroFrame object with the requested size using
371 * the data pointed to by @data. The data must be in v216 format.
372 * The data must remain for the lifetime of the SchroFrame object.
373 * It is recommended to use schro_frame_set_free_callback() for
374 * notification when the data is no longer needed.
375 *
376 * Returns: a new SchroFrame object
377 */
378 SchroFrame *
schro_frame_new_from_data_v216(void * data,int width,int height)379 schro_frame_new_from_data_v216 (void *data, int width, int height)
380 {
381 SchroFrame *frame = schro_frame_new ();
382
383 frame->format = SCHRO_FRAME_FORMAT_v216;
384
385 frame->width = width;
386 frame->height = height;
387
388 frame->components[0].format = frame->format;
389 frame->components[0].width = width;
390 frame->components[0].height = height;
391 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 4;
392 frame->components[0].data = data;
393 frame->components[0].length = frame->components[0].stride * height;
394 frame->components[0].v_shift = 0;
395 frame->components[0].h_shift = 0;
396
397 return frame;
398 }
399
400 /**
401 * schro_frame_new_from_data_v210:
402 *
403 * Creates a new SchroFrame object with the requested size using
404 * the data pointed to by @data. The data must be in v210 format.
405 * The data must remain for the lifetime of the SchroFrame object.
406 * It is recommended to use schro_frame_set_free_callback() for
407 * notification when the data is no longer needed.
408 *
409 * Returns: a new SchroFrame object
410 */
411 SchroFrame *
schro_frame_new_from_data_v210(void * data,int width,int height)412 schro_frame_new_from_data_v210 (void *data, int width, int height)
413 {
414 SchroFrame *frame = schro_frame_new ();
415
416 frame->format = SCHRO_FRAME_FORMAT_v210;
417
418 frame->width = width;
419 frame->height = height;
420
421 frame->components[0].format = frame->format;
422 frame->components[0].width = width;
423 frame->components[0].height = height;
424 frame->components[0].stride = ((width + 47) / 48) * 128;
425 frame->components[0].data = data;
426 frame->components[0].length = frame->components[0].stride * height;
427 frame->components[0].v_shift = 0;
428 frame->components[0].h_shift = 0;
429
430 return frame;
431 }
432
433 /**
434 * schro_frame_new_from_data_I420:
435 *
436 * Creates a new SchroFrame object with the requested size using
437 * the data pointed to by @data. The data must be in I420 format.
438 * The data must remain for the lifetime of the SchroFrame object.
439 * It is recommended to use schro_frame_set_free_callback() for
440 * notification when the data is no longer needed.
441 *
442 * Returns: a new SchroFrame object
443 */
444 SchroFrame *
schro_frame_new_from_data_I420(void * data,int width,int height)445 schro_frame_new_from_data_I420 (void *data, int width, int height)
446 {
447 SchroFrame *frame = schro_frame_new ();
448
449 frame->format = SCHRO_FRAME_FORMAT_U8_420;
450
451 frame->width = width;
452 frame->height = height;
453
454 frame->components[0].format = frame->format;
455 frame->components[0].width = width;
456 frame->components[0].height = height;
457 frame->components[0].stride = ROUND_UP_POW2 (width, 2);
458 frame->components[0].data = data;
459 frame->components[0].length = frame->components[0].stride *
460 ROUND_UP_POW2 (frame->components[0].height, 1);
461 frame->components[0].v_shift = 0;
462 frame->components[0].h_shift = 0;
463
464 frame->components[1].format = frame->format;
465 frame->components[1].width = ROUND_UP_SHIFT (width, 1);
466 frame->components[1].height = ROUND_UP_SHIFT (height, 1);
467 frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
468 frame->components[1].length =
469 frame->components[1].stride * frame->components[1].height;
470 frame->components[1].data = SCHRO_OFFSET (frame->components[0].data,
471 frame->components[0].length);
472 frame->components[1].v_shift = 1;
473 frame->components[1].h_shift = 1;
474
475 frame->components[2].format = frame->format;
476 frame->components[2].width = ROUND_UP_SHIFT (width, 1);
477 frame->components[2].height = ROUND_UP_SHIFT (height, 1);
478 frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
479 frame->components[2].length =
480 frame->components[2].stride * frame->components[2].height;
481 frame->components[2].data = SCHRO_OFFSET (frame->components[1].data,
482 frame->components[1].length);
483 frame->components[2].v_shift = 1;
484 frame->components[2].h_shift = 1;
485
486 return frame;
487 }
488
489 /**
490 * schro_frame_new_from_data_Y42B:
491 *
492 * Creates a new SchroFrame object with the requested size using
493 * the data pointed to by @data. The data must be in Y42B format.
494 * The data must remain for the lifetime of the SchroFrame object.
495 * It is recommended to use schro_frame_set_free_callback() for
496 * notification when the data is no longer needed.
497 *
498 * Returns: a new SchroFrame object
499 */
500 SchroFrame *
schro_frame_new_from_data_Y42B(void * data,int width,int height)501 schro_frame_new_from_data_Y42B (void *data, int width, int height)
502 {
503 SchroFrame *frame = schro_frame_new ();
504
505 frame->format = SCHRO_FRAME_FORMAT_U8_422;
506
507 frame->width = width;
508 frame->height = height;
509
510 frame->components[0].format = frame->format;
511 frame->components[0].width = width;
512 frame->components[0].height = height;
513 frame->components[0].stride = ROUND_UP_POW2 (width, 2);
514 frame->components[0].data = data;
515 frame->components[0].length = frame->components[0].stride *
516 ROUND_UP_POW2 (frame->components[0].height, 1);
517 frame->components[0].v_shift = 0;
518 frame->components[0].h_shift = 0;
519
520 frame->components[1].format = frame->format;
521 frame->components[1].width = ROUND_UP_SHIFT (width, 1);
522 frame->components[1].height = height;
523 frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
524 frame->components[1].length =
525 frame->components[1].stride * frame->components[1].height;
526 frame->components[1].data = SCHRO_OFFSET (frame->components[0].data,
527 frame->components[0].length);
528 frame->components[1].v_shift = 0;
529 frame->components[1].h_shift = 1;
530
531 frame->components[2].format = frame->format;
532 frame->components[2].width = ROUND_UP_SHIFT (width, 1);
533 frame->components[2].height = height;
534 frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
535 frame->components[2].length =
536 frame->components[2].stride * frame->components[2].height;
537 frame->components[2].data = SCHRO_OFFSET (frame->components[1].data,
538 frame->components[1].length);
539 frame->components[2].v_shift = 0;
540 frame->components[2].h_shift = 1;
541
542 return frame;
543 }
544
545 /**
546 * schro_frame_new_from_data_Y444:
547 *
548 * Creates a new SchroFrame object with the requested size using
549 * the data pointed to by @data. The data must be in Y444 format.
550 * The data must remain for the lifetime of the SchroFrame object.
551 * It is recommended to use schro_frame_set_free_callback() for
552 * notification when the data is no longer needed.
553 *
554 * Returns: a new SchroFrame object
555 */
556 SchroFrame *
schro_frame_new_from_data_Y444(void * data,int width,int height)557 schro_frame_new_from_data_Y444 (void *data, int width, int height)
558 {
559 SchroFrame *frame = schro_frame_new ();
560
561 frame->format = SCHRO_FRAME_FORMAT_U8_444;
562
563 frame->width = width;
564 frame->height = height;
565
566 frame->components[0].format = frame->format;
567 frame->components[0].width = width;
568 frame->components[0].height = height;
569 frame->components[0].stride = ROUND_UP_POW2 (width, 2);
570 frame->components[0].data = data;
571 frame->components[0].length = frame->components[0].stride *
572 ROUND_UP_POW2 (frame->components[0].height, 1);
573 frame->components[0].v_shift = 0;
574 frame->components[0].h_shift = 0;
575
576 frame->components[1].format = frame->format;
577 frame->components[1].width = width;
578 frame->components[1].height = height;
579 frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
580 frame->components[1].length =
581 frame->components[1].stride * frame->components[1].height;
582 frame->components[1].data = SCHRO_OFFSET (frame->components[0].data,
583 frame->components[0].length);
584 frame->components[1].v_shift = 0;
585 frame->components[1].h_shift = 0;
586
587 frame->components[2].format = frame->format;
588 frame->components[2].width = width;
589 frame->components[2].height = height;
590 frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
591 frame->components[2].length =
592 frame->components[2].stride * frame->components[2].height;
593 frame->components[2].data = SCHRO_OFFSET (frame->components[1].data,
594 frame->components[1].length);
595 frame->components[2].v_shift = 0;
596 frame->components[2].h_shift = 0;
597
598 return frame;
599 }
600
601 /**
602 * schro_frame_new_from_data_YV12:
603 *
604 * Creates a new SchroFrame object with the requested size using
605 * the data pointed to by @data. The data must be in YV12 format.
606 * The data must remain for the lifetime of the SchroFrame object.
607 * It is recommended to use schro_frame_set_free_callback() for
608 * notification when the data is no longer needed.
609 *
610 * Returns: a new SchroFrame object
611 */
612 SchroFrame *
schro_frame_new_from_data_YV12(void * data,int width,int height)613 schro_frame_new_from_data_YV12 (void *data, int width, int height)
614 {
615 SchroFrame *frame = schro_frame_new ();
616
617 frame->format = SCHRO_FRAME_FORMAT_U8_420;
618
619 frame->width = width;
620 frame->height = height;
621
622 frame->components[0].format = frame->format;
623 frame->components[0].width = width;
624 frame->components[0].height = height;
625 frame->components[0].stride = ROUND_UP_POW2 (width, 2);
626 frame->components[0].data = data;
627 frame->components[0].length = frame->components[0].stride *
628 ROUND_UP_POW2 (frame->components[0].height, 1);
629 frame->components[0].v_shift = 0;
630 frame->components[0].h_shift = 0;
631
632 frame->components[2].format = frame->format;
633 frame->components[2].width = ROUND_UP_SHIFT (width, 1);
634 frame->components[2].height = ROUND_UP_SHIFT (height, 1);
635 frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2);
636 frame->components[2].length =
637 frame->components[2].stride * frame->components[2].height;
638 frame->components[2].data = SCHRO_OFFSET (frame->components[0].data,
639 frame->components[0].length);
640 frame->components[2].v_shift = 1;
641 frame->components[2].h_shift = 1;
642
643 frame->components[1].format = frame->format;
644 frame->components[1].width = ROUND_UP_SHIFT (width, 1);
645 frame->components[1].height = ROUND_UP_SHIFT (height, 1);
646 frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2);
647 frame->components[1].length =
648 frame->components[1].stride * frame->components[1].height;
649 frame->components[1].data = SCHRO_OFFSET (frame->components[2].data,
650 frame->components[2].length);
651 frame->components[1].v_shift = 1;
652 frame->components[1].h_shift = 1;
653
654 return frame;
655 }
656
657 /**
658 * schro_frame_dup:
659 *
660 * Creates a new SchroFrame object with the same dimensions and format
661 * as @frame, and copies the data from the @frame to the new object.
662 *
663 * Returns: a new SchroFrame object
664 */
665 SchroFrame *
schro_frame_dup(SchroFrame * frame)666 schro_frame_dup (SchroFrame * frame)
667 {
668 return schro_frame_dup_extended (frame, 0);
669 }
670
671 SchroFrame *
schro_frame_dup_extended(SchroFrame * frame,int extension)672 schro_frame_dup_extended (SchroFrame * frame, int extension)
673 {
674 return schro_frame_dup_full (frame, extension, FALSE);
675 }
676
677 SchroFrame *
schro_frame_dup_full(SchroFrame * frame,int extension,int is_upsampled)678 schro_frame_dup_full (SchroFrame * frame, int extension, int is_upsampled)
679 {
680 SchroFrame *dup_frame;
681
682 dup_frame = schro_frame_new_and_alloc_full (frame->domain,
683 frame->format, frame->width, frame->height, extension, is_upsampled);
684 schro_frame_convert (dup_frame, frame);
685
686 return dup_frame;
687 }
688
689 /**
690 * schro_frame_clone:
691 *
692 * Creates a new SchroFrame object with the same dimensions and format
693 * as @frame. This function leaves the data in the new object
694 * uninitialized.
695 *
696 * Returns: a new SchroFrame object
697 */
698 SchroFrame *
schro_frame_clone(SchroMemoryDomain * domain,SchroFrame * frame)699 schro_frame_clone (SchroMemoryDomain * domain, SchroFrame * frame)
700 {
701 return schro_frame_new_and_alloc (domain,
702 frame->format, frame->width, frame->height);
703 }
704
705
706 /**
707 * schro_frame_ref:
708 * @frame: a frame object
709 *
710 * Increases the reference count of @frame.
711 *
712 * Returns: the value of @frame
713 */
714 SchroFrame *
schro_frame_ref(SchroFrame * frame)715 schro_frame_ref (SchroFrame * frame)
716 {
717 SCHRO_ASSERT (frame && frame->refcount > 0);
718 schro_mutex_lock (frame_mutex);
719 frame->refcount++;
720 schro_mutex_unlock (frame_mutex);
721 return frame;
722 }
723
724
725 /**
726 * schro_frame_unref:
727 * @frame: a frame object
728 *
729 * Decreases the reference count of @frame. If the new reference
730 * count is 0, the frame is freed. If a frame free callback was
731 * set, this function is called.
732 *
733 * Returns: the value of @frame
734 */
735 void
schro_frame_unref(SchroFrame * frame)736 schro_frame_unref (SchroFrame * frame)
737 {
738 int i;
739
740 SCHRO_ASSERT (frame->refcount > 0);
741
742 schro_mutex_lock (frame_mutex);
743 frame->refcount--;
744 if (frame->refcount == 0) {
745 schro_mutex_unlock (frame_mutex);
746 if (frame->free) {
747 frame->free (frame, frame->priv);
748 }
749 #ifdef HAVE_OPENGL
750 if (SCHRO_FRAME_IS_OPENGL (frame)) {
751 schro_opengl_frame_cleanup (frame);
752 }
753 #endif
754
755 for (i = 0; i < 3; i++) {
756 if (frame->regions[i]) {
757 if (frame->domain) {
758 schro_memory_domain_memfree (frame->domain, frame->regions[i]);
759 } else {
760 free (frame->regions[i]);
761 }
762 }
763 }
764
765 if (frame->virt_frame1) {
766 schro_frame_unref (frame->virt_frame1);
767 }
768 if (frame->virt_frame2) {
769 schro_frame_unref (frame->virt_frame2);
770 }
771 if (frame->virt_priv) {
772 schro_free (frame->virt_priv);
773 }
774
775 schro_free (frame);
776 } else {
777 schro_mutex_unlock (frame_mutex);
778 }
779 }
780
781 /**
782 * schro_frame_set_free_callback:
783 * @frame: a frame object
784 * @free_func: the function to call when the frame is freed
785 * @priv: callback key
786 *
787 * Sets a function that will be called when the object reference
788 * count drops to zero and the object is freed.
789 */
790 void
schro_frame_set_free_callback(SchroFrame * frame,SchroFrameFreeFunc free_func,void * priv)791 schro_frame_set_free_callback (SchroFrame * frame,
792 SchroFrameFreeFunc free_func, void *priv)
793 {
794 frame->free = free_func;
795 frame->priv = priv;
796 }
797
798 static void
schro_frame_component_clear(SchroFrameData * fd)799 schro_frame_component_clear (SchroFrameData * fd)
800 {
801 //int j;
802
803 if (SCHRO_FRAME_FORMAT_DEPTH (fd->format) == SCHRO_FRAME_FORMAT_DEPTH_U8) {
804 orc_splat_u8_2d (fd->data, fd->stride, 0, fd->width, fd->height);
805 } else {
806 orc_splat_s16_2d (fd->data, fd->stride, 0, fd->width, fd->height);
807 }
808 }
809
810 void
schro_frame_clear(SchroFrame * frame)811 schro_frame_clear (SchroFrame * frame)
812 {
813 schro_frame_component_clear (frame->components + 0);
814 schro_frame_component_clear (frame->components + 1);
815 schro_frame_component_clear (frame->components + 2);
816 }
817
818 typedef void (*SchroFrameBinaryFunc) (SchroFrame * dest, SchroFrame * src);
819
820 struct binary_struct
821 {
822 SchroFrameFormat from;
823 SchroFrameFormat to;
824 SchroFrameBinaryFunc func;
825 };
826
827 /**
828 * schro_frame_convert:
829 * @dest: destination frame
830 * @src: source frame
831 *
832 * Copies data from the source frame to the destination frame, converting
833 * formats if necessary. Only a few conversions are supported.
834 */
835 void
schro_frame_convert(SchroFrame * dest,SchroFrame * src)836 schro_frame_convert (SchroFrame * dest, SchroFrame * src)
837 {
838 SchroFrame *frame;
839 SchroFrameFormat dest_format;
840
841 SCHRO_ASSERT (dest != NULL);
842 SCHRO_ASSERT (src != NULL);
843
844 switch (dest->format) {
845 case SCHRO_FRAME_FORMAT_YUYV:
846 case SCHRO_FRAME_FORMAT_UYVY:
847 dest_format = SCHRO_FRAME_FORMAT_U8_422;
848 break;
849 case SCHRO_FRAME_FORMAT_AYUV:
850 case SCHRO_FRAME_FORMAT_ARGB:
851 dest_format = SCHRO_FRAME_FORMAT_U8_444;
852 break;
853 case SCHRO_FRAME_FORMAT_v210:
854 case SCHRO_FRAME_FORMAT_v216:
855 dest_format = SCHRO_FRAME_FORMAT_S16_422;
856 break;
857 case SCHRO_FRAME_FORMAT_AY64:
858 dest_format = SCHRO_FRAME_FORMAT_S32_444;
859 break;
860 default:
861 dest_format = dest->format;
862 break;
863 }
864 schro_frame_ref (src);
865
866 frame = schro_virt_frame_new_unpack (src);
867 SCHRO_DEBUG ("unpack %p", frame);
868
869 if (SCHRO_FRAME_FORMAT_DEPTH (dest_format) !=
870 SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
871 if (SCHRO_FRAME_FORMAT_DEPTH (dest_format) == SCHRO_FRAME_FORMAT_DEPTH_U8) {
872 if (SCHRO_FRAME_FORMAT_DEPTH (src->format) == SCHRO_FRAME_FORMAT_DEPTH_S16) {
873 frame = schro_virt_frame_new_convert_u8 (frame);
874 SCHRO_DEBUG ("convert_u8 %p", frame);
875 } else {
876 frame = schro_virt_frame_new_convert_u8_s32 (frame);
877 SCHRO_DEBUG("convert u8 s32");
878 }
879 } else if (SCHRO_FRAME_FORMAT_DEPTH (dest_format) ==
880 SCHRO_FRAME_FORMAT_DEPTH_S16) {
881 frame = schro_virt_frame_new_convert_s16 (frame);
882 SCHRO_DEBUG ("convert_s16 %p", frame);
883 } else if (SCHRO_FRAME_FORMAT_DEPTH (dest_format) ==
884 SCHRO_FRAME_FORMAT_DEPTH_S32) {
885 frame = schro_virt_frame_new_convert_s32 (frame);
886 SCHRO_DEBUG ("convert_s32 %p", frame);
887 }
888 }
889
890 if ((dest_format & 3) != (frame->format & 3)) {
891 frame = schro_virt_frame_new_subsample (frame, dest_format);
892 SCHRO_DEBUG ("subsample %p", frame);
893 }
894
895 if (dest->width < frame->width || dest->height < frame->height) {
896 SCHRO_DEBUG ("crop %d %d to %d %d",
897 frame->width, frame->height, dest->width, dest->height);
898
899 frame = schro_virt_frame_new_crop (frame, dest->width, dest->height);
900 SCHRO_DEBUG ("crop %p", frame);
901 }
902 if (dest->width > src->width || dest->height > src->height) {
903 frame = schro_virt_frame_new_edgeextend (frame, dest->width, dest->height);
904 SCHRO_DEBUG ("edgeextend %p", frame);
905 }
906
907 switch (dest->format) {
908 case SCHRO_FRAME_FORMAT_YUYV:
909 frame = schro_virt_frame_new_pack_YUY2 (frame);
910 SCHRO_DEBUG ("pack_YUY2 %p", frame);
911 break;
912 case SCHRO_FRAME_FORMAT_UYVY:
913 frame = schro_virt_frame_new_pack_UYVY (frame);
914 SCHRO_DEBUG ("pack_UYVY %p", frame);
915 break;
916 case SCHRO_FRAME_FORMAT_AYUV:
917 frame = schro_virt_frame_new_pack_AYUV (frame);
918 SCHRO_DEBUG ("pack_AYUV %p", frame);
919 break;
920 case SCHRO_FRAME_FORMAT_v210:
921 frame = schro_virt_frame_new_pack_v210 (frame);
922 SCHRO_DEBUG ("pack_v210 %p", frame);
923 break;
924 case SCHRO_FRAME_FORMAT_v216:
925 frame = schro_virt_frame_new_pack_v216 (frame);
926 SCHRO_DEBUG ("pack_v216 %p", frame);
927 break;
928 case SCHRO_FRAME_FORMAT_AY64:
929 frame = schro_virt_frame_new_pack_AY64 (frame);
930 SCHRO_DEBUG ("pack_AY64 %p", frame);
931 break;
932 default:
933 break;
934 }
935
936 schro_virt_frame_render (frame, dest);
937 schro_frame_unref (frame);
938
939 }
940
941 static void schro_frame_add_s16_s16 (SchroFrame * dest, SchroFrame * src);
942 static void schro_frame_add_s16_u8 (SchroFrame * dest, SchroFrame * src);
943
944 static struct binary_struct schro_frame_add_func_list[] = {
945 {SCHRO_FRAME_FORMAT_S16_444, SCHRO_FRAME_FORMAT_S16_444,
946 schro_frame_add_s16_s16},
947 {SCHRO_FRAME_FORMAT_S16_422, SCHRO_FRAME_FORMAT_S16_422,
948 schro_frame_add_s16_s16},
949 {SCHRO_FRAME_FORMAT_S16_420, SCHRO_FRAME_FORMAT_S16_420,
950 schro_frame_add_s16_s16},
951
952 {SCHRO_FRAME_FORMAT_U8_444, SCHRO_FRAME_FORMAT_S16_444,
953 schro_frame_add_s16_u8},
954 {SCHRO_FRAME_FORMAT_U8_422, SCHRO_FRAME_FORMAT_S16_422,
955 schro_frame_add_s16_u8},
956 {SCHRO_FRAME_FORMAT_U8_420, SCHRO_FRAME_FORMAT_S16_420,
957 schro_frame_add_s16_u8},
958
959 {0}
960 };
961
962 /**
963 * schro_frame_add:
964 * @dest: destination frame
965 * @src: source frame
966 *
967 * Adds data from the source frame to the destination frame. The
968 * frames must have the same chroma subsampling, and only a few
969 * combinations of bit depths are supported.
970 */
971 void
schro_frame_add(SchroFrame * dest,SchroFrame * src)972 schro_frame_add (SchroFrame * dest, SchroFrame * src)
973 {
974 int i;
975
976 SCHRO_ASSERT (dest != NULL);
977 SCHRO_ASSERT (src != NULL);
978
979 for (i = 0; schro_frame_add_func_list[i].func; i++) {
980 if (schro_frame_add_func_list[i].from == src->format &&
981 schro_frame_add_func_list[i].to == dest->format) {
982 schro_frame_add_func_list[i].func (dest, src);
983 return;
984 }
985 }
986
987 SCHRO_ERROR ("add function unimplemented");
988 SCHRO_ASSERT (0);
989 }
990
991 static void schro_frame_subtract_s16_s16 (SchroFrame * dest, SchroFrame * src);
992 static void schro_frame_subtract_s16_u8 (SchroFrame * dest, SchroFrame * src);
993
994 static struct binary_struct schro_frame_subtract_func_list[] = {
995 {SCHRO_FRAME_FORMAT_S16_444, SCHRO_FRAME_FORMAT_S16_444,
996 schro_frame_subtract_s16_s16},
997 {SCHRO_FRAME_FORMAT_S16_422, SCHRO_FRAME_FORMAT_S16_422,
998 schro_frame_subtract_s16_s16},
999 {SCHRO_FRAME_FORMAT_S16_420, SCHRO_FRAME_FORMAT_S16_420,
1000 schro_frame_subtract_s16_s16},
1001
1002 {SCHRO_FRAME_FORMAT_U8_444, SCHRO_FRAME_FORMAT_S16_444,
1003 schro_frame_subtract_s16_u8},
1004 {SCHRO_FRAME_FORMAT_U8_422, SCHRO_FRAME_FORMAT_S16_422,
1005 schro_frame_subtract_s16_u8},
1006 {SCHRO_FRAME_FORMAT_U8_420, SCHRO_FRAME_FORMAT_S16_420,
1007 schro_frame_subtract_s16_u8},
1008
1009 {0}
1010 };
1011
1012 /**
1013 * schro_frame_subtract:
1014 * @dest: destination frame
1015 * @src: source frame
1016 *
1017 * Subtracts data from the source frame to the destination frame. The
1018 * frames must have the same chroma subsampling, and only a few
1019 * combinations of bit depths are supported.
1020 */
1021 void
schro_frame_subtract(SchroFrame * dest,SchroFrame * src)1022 schro_frame_subtract (SchroFrame * dest, SchroFrame * src)
1023 {
1024 int i;
1025
1026 SCHRO_ASSERT (dest != NULL);
1027 SCHRO_ASSERT (src != NULL);
1028
1029 for (i = 0; schro_frame_subtract_func_list[i].func; i++) {
1030 if (schro_frame_subtract_func_list[i].from == src->format &&
1031 schro_frame_subtract_func_list[i].to == dest->format) {
1032 schro_frame_subtract_func_list[i].func (dest, src);
1033 return;
1034 }
1035 }
1036
1037 SCHRO_ERROR (0);
1038 SCHRO_ASSERT ("subtract function unimplemented");
1039 }
1040
1041
1042 static void
schro_frame_add_s16_s16(SchroFrame * dest,SchroFrame * src)1043 schro_frame_add_s16_s16 (SchroFrame * dest, SchroFrame * src)
1044 {
1045 SchroFrameData *dcomp;
1046 SchroFrameData *scomp;
1047 int i;
1048 int width, height;
1049
1050 for (i = 0; i < 3; i++) {
1051 dcomp = &dest->components[i];
1052 scomp = &src->components[i];
1053
1054 width = MIN (dcomp->width, scomp->width);
1055 height = MIN (dcomp->height, scomp->height);
1056
1057 orc_add_s16_2d (dcomp->data, dcomp->stride,
1058 scomp->data, scomp->stride, width, height);
1059 }
1060 }
1061
1062 static void
schro_frame_add_s16_u8(SchroFrame * dest,SchroFrame * src)1063 schro_frame_add_s16_u8 (SchroFrame * dest, SchroFrame * src)
1064 {
1065 SchroFrameData *dcomp;
1066 SchroFrameData *scomp;
1067 //int16_t *ddata;
1068 //uint8_t *sdata;
1069 int i;
1070 //int y;
1071 int width, height;
1072
1073 for (i = 0; i < 3; i++) {
1074 dcomp = &dest->components[i];
1075 scomp = &src->components[i];
1076
1077 width = MIN (dcomp->width, scomp->width);
1078 height = MIN (dcomp->height, scomp->height);
1079
1080 orc_add_s16_u8_2d (dcomp->data, dcomp->stride,
1081 scomp->data, scomp->stride, width, height);
1082 #if 0
1083 for (y = 0; y < height; y++) {
1084 sdata = SCHRO_FRAME_DATA_GET_LINE (scomp, y);
1085 ddata = SCHRO_FRAME_DATA_GET_LINE (dcomp, y);
1086 orc_add_s16_u8 (ddata, ddata, sdata, width);
1087 }
1088 #endif
1089 }
1090 }
1091
1092 static void
schro_frame_subtract_s16_s16(SchroFrame * dest,SchroFrame * src)1093 schro_frame_subtract_s16_s16 (SchroFrame * dest, SchroFrame * src)
1094 {
1095 SchroFrameData *dcomp;
1096 SchroFrameData *scomp;
1097 int16_t *ddata;
1098 int16_t *sdata;
1099 int i;
1100 int y;
1101 int width, height;
1102
1103 for (i = 0; i < 3; i++) {
1104 dcomp = &dest->components[i];
1105 scomp = &src->components[i];
1106
1107 width = MIN (dcomp->width, scomp->width);
1108 height = MIN (dcomp->height, scomp->height);
1109
1110 for (y = 0; y < height; y++) {
1111 sdata = SCHRO_FRAME_DATA_GET_LINE (scomp, y);
1112 ddata = SCHRO_FRAME_DATA_GET_LINE (dcomp, y);
1113 orc_subtract_s16 (ddata, ddata, sdata, width);
1114 }
1115 }
1116 }
1117
1118 static void
schro_frame_subtract_s16_u8(SchroFrame * dest,SchroFrame * src)1119 schro_frame_subtract_s16_u8 (SchroFrame * dest, SchroFrame * src)
1120 {
1121 SchroFrameData *dcomp;
1122 SchroFrameData *scomp;
1123 int16_t *ddata;
1124 uint8_t *sdata;
1125 int i;
1126 int y;
1127 int width, height;
1128
1129 for (i = 0; i < 3; i++) {
1130 dcomp = &dest->components[i];
1131 scomp = &src->components[i];
1132
1133 width = MIN (dcomp->width, scomp->width);
1134 height = MIN (dcomp->height, scomp->height);
1135
1136 for (y = 0; y < height; y++) {
1137 sdata = SCHRO_FRAME_DATA_GET_LINE (scomp, y);
1138 ddata = SCHRO_FRAME_DATA_GET_LINE (dcomp, y);
1139 orc_subtract_s16_u8 (ddata, ddata, sdata, width);
1140 }
1141 }
1142 }
1143
1144 /**
1145 * schro_frame_iwt_transform:
1146 * @frame: frame
1147 * @params: transform parameters
1148 *
1149 * Performs an in-place integer wavelet transform on @frame. The
1150 * frame must have a bit depth of 16.
1151 */
1152 void
schro_frame_iwt_transform(SchroFrame * frame,SchroParams * params)1153 schro_frame_iwt_transform (SchroFrame * frame, SchroParams * params)
1154 {
1155 int component;
1156 int width;
1157 int height;
1158 int level;
1159 int16_t *tmp;
1160
1161 tmp = schro_malloc (sizeof (int16_t) * (params->iwt_luma_width + 16));
1162
1163 for (component = 0; component < 3; component++) {
1164 SchroFrameData *comp = &frame->components[component];
1165
1166 if (component == 0) {
1167 width = params->iwt_luma_width;
1168 height = params->iwt_luma_height;
1169 } else {
1170 width = params->iwt_chroma_width;
1171 height = params->iwt_chroma_height;
1172 }
1173
1174 for (level = 0; level < params->transform_depth; level++) {
1175 SchroFrameData fd;
1176
1177 fd.format = frame->format;
1178 fd.data = comp->data;
1179 fd.width = width >> level;
1180 fd.height = height >> level;
1181 fd.stride = comp->stride << level;
1182
1183 schro_wavelet_transform_2d (&fd, params->wavelet_filter_index, tmp);
1184 }
1185 }
1186
1187 schro_free (tmp);
1188 }
1189
1190 /**
1191 * schro_frame_shift_left:
1192 * @frame: frame
1193 * @shift: number of bits to shift
1194 *
1195 * Shifts each value in @frame to the left by @shift bits. This
1196 * operation happens in-place.
1197 */
1198 void
schro_frame_shift_left(SchroFrame * frame,int shift)1199 schro_frame_shift_left (SchroFrame * frame, int shift)
1200 {
1201 SchroFrameData *comp;
1202 int16_t *data;
1203 int i;
1204 int y;
1205
1206 for (i = 0; i < 3; i++) {
1207 comp = &frame->components[i];
1208
1209 for (y = 0; y < comp->height; y++) {
1210 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1211 orc_lshift_s16_ip (data, shift, comp->width);
1212 }
1213 }
1214 }
1215
1216 /**
1217 * schro_frame_shift_right:
1218 * @frame: frame
1219 * @shift: number of bits to shift
1220 *
1221 * Shifts each value in @frame to the right by @shift bits. This
1222 * operation happens in-place.
1223 */
1224 void
schro_frame_shift_right(SchroFrame * frame,int shift)1225 schro_frame_shift_right (SchroFrame * frame, int shift)
1226 {
1227 SchroFrameData *comp;
1228 int i;
1229 int y;
1230
1231 if (SCHRO_FRAME_FORMAT_DEPTH (frame->format) ==
1232 SCHRO_FRAME_FORMAT_DEPTH_S16) {
1233 int16_t *data;
1234 for (i = 0; i < 3; i++) {
1235 comp = &frame->components[i];
1236
1237 for (y = 0; y < comp->height; y++) {
1238 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1239 orc_add_const_rshift_s16 (data, (1 << shift) >> 1, shift, comp->width);
1240 }
1241 }
1242 } else {
1243 int32_t *data;
1244 for (i = 0; i < 3; i++) {
1245 comp = &frame->components[i];
1246
1247 for (y = 0; y < comp->height; y++) {
1248 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1249 orc_add_const_rshift_s32 (data, (1 << shift) >> 1, shift, comp->width);
1250 }
1251 }
1252 }
1253 }
1254
1255 #ifdef unused
1256 /**
1257 * schro_frame_edge_extend:
1258 * @frame: frame
1259 * @width: width of subpicture
1260 * @height: height of subpicture
1261 *
1262 * Extends the edges of the subpicture defined from 0,0 to @width,@height
1263 * to the size of @frame.
1264 */
1265 void
schro_frame_edge_extend(SchroFrame * frame,int width,int height)1266 schro_frame_edge_extend (SchroFrame * frame, int width, int height)
1267 {
1268 SchroFrameData *comp;
1269 int i;
1270 int y;
1271 int chroma_width;
1272 int chroma_height;
1273
1274 SCHRO_DEBUG ("extending %d %d -> %d %d", width, height,
1275 frame->width, frame->height);
1276
1277 chroma_width = ROUND_UP_SHIFT (width,
1278 SCHRO_FRAME_FORMAT_H_SHIFT (frame->format));
1279 chroma_height = ROUND_UP_SHIFT (height,
1280 SCHRO_FRAME_FORMAT_V_SHIFT (frame->format));
1281
1282 SCHRO_DEBUG ("chroma %d %d -> %d %d", chroma_width, chroma_height,
1283 frame->components[1].width, frame->components[1].height);
1284
1285 switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
1286 case SCHRO_FRAME_FORMAT_DEPTH_U8:
1287 for (i = 0; i < 3; i++) {
1288 uint8_t *data;
1289 int w, h;
1290
1291 comp = &frame->components[i];
1292 data = comp->data;
1293
1294 w = (i > 0) ? chroma_width : width;
1295 h = (i > 0) ? chroma_height : height;
1296
1297 if (w < comp->width) {
1298 for (y = 0; y < MIN (h, comp->height); y++) {
1299 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1300 orc_splat_u8_ns (data + w, data[w - 1], comp->width - w);
1301 }
1302 }
1303 for (y = h; y < comp->height; y++) {
1304 orc_memcpy (SCHRO_FRAME_DATA_GET_LINE (comp, y),
1305 SCHRO_FRAME_DATA_GET_LINE (comp, h - 1), comp->width);
1306 }
1307 }
1308 break;
1309 case SCHRO_FRAME_FORMAT_DEPTH_S16:
1310 for (i = 0; i < 3; i++) {
1311 int16_t *data;
1312 int w, h;
1313
1314 comp = &frame->components[i];
1315 data = comp->data;
1316
1317 w = (i > 0) ? chroma_width : width;
1318 h = (i > 0) ? chroma_height : height;
1319
1320 if (w < comp->width) {
1321 for (y = 0; y < MIN (h, comp->height); y++) {
1322 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1323 orc_splat_s16_ns (data + w, data[w - 1], comp->width - w);
1324 }
1325 }
1326 for (y = h; y < comp->height; y++) {
1327 orc_memcpy (SCHRO_FRAME_DATA_GET_LINE (comp, y),
1328 SCHRO_FRAME_DATA_GET_LINE (comp, h - 1), comp->width * 2);
1329 }
1330 }
1331 break;
1332 default:
1333 SCHRO_ERROR ("unimplemented case");
1334 SCHRO_ASSERT (0);
1335 break;
1336 }
1337 }
1338 #endif
1339
1340 void
schro_frame_zero_extend(SchroFrame * frame,int width,int height)1341 schro_frame_zero_extend (SchroFrame * frame, int width, int height)
1342 {
1343 SchroFrameData *comp;
1344 int i;
1345 int y;
1346 int chroma_width;
1347 int chroma_height;
1348
1349 SCHRO_DEBUG ("extending %d %d -> %d %d", width, height,
1350 frame->width, frame->height);
1351
1352 chroma_width = ROUND_UP_SHIFT (width,
1353 SCHRO_FRAME_FORMAT_H_SHIFT (frame->format));
1354 chroma_height = ROUND_UP_SHIFT (height,
1355 SCHRO_FRAME_FORMAT_V_SHIFT (frame->format));
1356
1357 switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
1358 case SCHRO_FRAME_FORMAT_DEPTH_U8:
1359 for (i = 0; i < 3; i++) {
1360 uint8_t *data;
1361 int w, h;
1362
1363 comp = &frame->components[i];
1364 data = comp->data;
1365
1366 w = (i > 0) ? chroma_width : width;
1367 h = (i > 0) ? chroma_height : height;
1368
1369 if (w < comp->width) {
1370 for (y = 0; y < h; y++) {
1371 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1372 orc_splat_u8_ns (data + w, 0, comp->width - w);
1373 }
1374 }
1375 for (y = h; y < comp->height; y++) {
1376 orc_splat_u8_ns (SCHRO_FRAME_DATA_GET_LINE (comp, y), 0, comp->width);
1377 }
1378 }
1379 break;
1380 case SCHRO_FRAME_FORMAT_DEPTH_S16:
1381 for (i = 0; i < 3; i++) {
1382 int16_t *data;
1383 int w, h;
1384
1385 comp = &frame->components[i];
1386 data = comp->data;
1387
1388 w = (i > 0) ? chroma_width : width;
1389 h = (i > 0) ? chroma_height : height;
1390
1391 if (w < comp->width) {
1392 for (y = 0; y < h; y++) {
1393 data = SCHRO_FRAME_DATA_GET_LINE (comp, y);
1394 orc_splat_s16_ns (data + w, 0, comp->width - w);
1395 }
1396 }
1397 for (y = h; y < comp->height; y++) {
1398 orc_splat_s16_ns (SCHRO_FRAME_DATA_GET_LINE (comp, y), 0,
1399 comp->width);
1400 }
1401 }
1402 break;
1403 default:
1404 SCHRO_ERROR ("unimplemented case");
1405 break;
1406 }
1407 }
1408
1409 static void
downsample_horiz_u8(uint8_t * dest,int n_dest,uint8_t * src,int n_src)1410 downsample_horiz_u8 (uint8_t * dest, int n_dest, uint8_t * src, int n_src)
1411 {
1412 int i;
1413
1414 if (n_dest < 4) {
1415 for (i = 0; i < n_dest; i++) {
1416 int x = 0;
1417 x += 6 * src[CLAMP (i * 2 - 1, 0, n_src - 1)];
1418 x += 26 * src[CLAMP (i * 2 + 0, 0, n_src - 1)];
1419 x += 26 * src[CLAMP (i * 2 + 1, 0, n_src - 1)];
1420 x += 6 * src[CLAMP (i * 2 + 2, 0, n_src - 1)];
1421 dest[i] = CLAMP ((x + 32) >> 6, 0, 255);
1422 }
1423 } else {
1424 for (i = 0; i < 1; i++) {
1425 int x = 0;
1426 x += 6 * src[CLAMP (i * 2 - 1, 0, n_src - 1)];
1427 x += 26 * src[CLAMP (i * 2 + 0, 0, n_src - 1)];
1428 x += 26 * src[CLAMP (i * 2 + 1, 0, n_src - 1)];
1429 x += 6 * src[CLAMP (i * 2 + 2, 0, n_src - 1)];
1430 dest[i] = CLAMP ((x + 32) >> 6, 0, 255);
1431 }
1432 orc_downsample_horiz_u8 (dest + 1, src, n_src / 2 - 2);
1433 for (i = n_src / 2 - 2; i < n_dest; i++) {
1434 int x = 0;
1435 x += 6 * src[CLAMP (i * 2 - 1, 0, n_src - 1)];
1436 x += 26 * src[CLAMP (i * 2 + 0, 0, n_src - 1)];
1437 x += 26 * src[CLAMP (i * 2 + 1, 0, n_src - 1)];
1438 x += 6 * src[CLAMP (i * 2 + 2, 0, n_src - 1)];
1439 dest[i] = CLAMP ((x + 32) >> 6, 0, 255);
1440 }
1441
1442 }
1443 }
1444
1445 static void
schro_frame_component_downsample(SchroFrameData * dest,SchroFrameData * src)1446 schro_frame_component_downsample (SchroFrameData * dest, SchroFrameData * src)
1447 {
1448 int i;
1449 uint8_t *tmp;
1450
1451 tmp = schro_malloc (src->width);
1452
1453 for (i = 0; i < dest->height; i++) {
1454 orc_downsample_vert_u8 (tmp,
1455 SCHRO_FRAME_DATA_GET_LINE (src, CLAMP (i * 2 - 1, 0, src->height - 1)),
1456 SCHRO_FRAME_DATA_GET_LINE (src, CLAMP (i * 2 + 0, 0, src->height - 1)),
1457 SCHRO_FRAME_DATA_GET_LINE (src, CLAMP (i * 2 + 1, 0, src->height - 1)),
1458 SCHRO_FRAME_DATA_GET_LINE (src, CLAMP (i * 2 + 2, 0, src->height - 1)),
1459 src->width);
1460 downsample_horiz_u8 (SCHRO_FRAME_DATA_GET_LINE (dest, i), dest->width,
1461 tmp, src->width);
1462 }
1463
1464 schro_free (tmp);
1465 }
1466
1467 void
schro_frame_downsample(SchroFrame * dest,SchroFrame * src)1468 schro_frame_downsample (SchroFrame * dest, SchroFrame * src)
1469 {
1470 schro_frame_component_downsample (&dest->components[0], &src->components[0]);
1471 schro_frame_component_downsample (&dest->components[1], &src->components[1]);
1472 schro_frame_component_downsample (&dest->components[2], &src->components[2]);
1473 }
1474
1475 static void
mas8_u8_edgeextend(uint8_t * d,const uint8_t * s,const int16_t * taps,int offset,int shift,int index_offset,int n)1476 mas8_u8_edgeextend (uint8_t * d, const uint8_t * s,
1477 const int16_t * taps, int offset, int shift, int index_offset, int n)
1478 {
1479 int i, j;
1480 int x;
1481
1482 if (n <= 8) {
1483 for (i = 0; i < n; i++) {
1484 x = 0;
1485 for (j = 0; j < 8; j++) {
1486 x += s[CLAMP (i + j - index_offset, 0, n - 1)] * taps[j];
1487 }
1488 d[i] = CLAMP ((x + offset) >> shift, 0, 255);
1489 }
1490 } else {
1491 for (i = 0; i < index_offset; i++) {
1492 x = 0;
1493 for (j = 0; j < 8; j++) {
1494 x += s[CLAMP (i + j - index_offset, 0, n - 1)] * taps[j];
1495 }
1496 d[i] = CLAMP ((x + offset) >> shift, 0, 255);
1497 }
1498 for (i = index_offset; i < n - 8 + index_offset; i++) {
1499 x = 0;
1500 for (j = 0; j < 8; j++) {
1501 x += s[i + j - index_offset] * taps[j];
1502 }
1503 d[i] = CLAMP ((x + offset) >> shift, 0, 255);
1504 }
1505 for (i = n - 8 + index_offset; i < n; i++) {
1506 x = 0;
1507 for (j = 0; j < 8; j++) {
1508 x += s[CLAMP (i + j - index_offset, 0, n - 1)] * taps[j];
1509 }
1510 d[i] = CLAMP ((x + offset) >> shift, 0, 255);
1511 }
1512 i = n - 1;
1513 d[i] = s[i];
1514 }
1515 }
1516
1517 void
schro_frame_upsample_horiz(SchroFrame * dest,SchroFrame * src)1518 schro_frame_upsample_horiz (SchroFrame * dest, SchroFrame * src)
1519 {
1520 int j, k;
1521 SchroFrameData *dcomp;
1522 SchroFrameData *scomp;
1523
1524 if (SCHRO_FRAME_FORMAT_DEPTH (dest->format) != SCHRO_FRAME_FORMAT_DEPTH_U8 ||
1525 SCHRO_FRAME_FORMAT_DEPTH (src->format) != SCHRO_FRAME_FORMAT_DEPTH_U8 ||
1526 src->format != dest->format) {
1527 SCHRO_ERROR ("unimplemented");
1528 return;
1529 }
1530
1531 for (k = 0; k < 3; k++) {
1532 static const int16_t taps[8] = { -1, 3, -7, 21, 21, -7, 3, -1 };
1533
1534 dcomp = &dest->components[k];
1535 scomp = &src->components[k];
1536
1537 for (j = 0; j < dcomp->height; j++) {
1538 mas8_u8_edgeextend (SCHRO_FRAME_DATA_GET_LINE (dcomp, j),
1539 SCHRO_FRAME_DATA_GET_LINE (scomp, j), taps, 16, 5, 3, scomp->width);
1540 }
1541 }
1542 }
1543
1544 static void
mas8_across_u8(uint8_t * dest,const uint8_t * src,int stride,const int16_t * weights,int offset,int shift,int n)1545 mas8_across_u8 (uint8_t * dest, const uint8_t * src, int stride,
1546 const int16_t * weights, int offset, int shift, int n)
1547 {
1548 int i;
1549 for (i = 0; i < n; i++) {
1550 int x = offset;
1551 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 0))[i] * weights[0];
1552 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 1))[i] * weights[1];
1553 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 2))[i] * weights[2];
1554 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 3))[i] * weights[3];
1555 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 4))[i] * weights[4];
1556 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 5))[i] * weights[5];
1557 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 6))[i] * weights[6];
1558 x += ((uint8_t *) SCHRO_OFFSET (src, stride * 7))[i] * weights[7];
1559 dest[i] = CLAMP (x >> shift, 0, 255);
1560 }
1561 }
1562
1563 static void
mas8_across_u8_slow(uint8_t * d,uint8_t ** s1_a8,const int16_t * s2_8,int offset,int shift,int n)1564 mas8_across_u8_slow (uint8_t * d, uint8_t ** s1_a8,
1565 const int16_t * s2_8, int offset, int shift, int n)
1566 {
1567 int i;
1568 int j;
1569 int x;
1570
1571 for (i = 0; i < n; i++) {
1572 x = 0;
1573 for (j = 0; j < 8; j++) {
1574 x += s1_a8[j][i] * s2_8[j];
1575 }
1576 d[i] = CLAMP ((x + offset) >> shift, 0, 255);
1577 }
1578 }
1579
1580 void
schro_frame_upsample_vert(SchroFrame * dest,SchroFrame * src)1581 schro_frame_upsample_vert (SchroFrame * dest, SchroFrame * src)
1582 {
1583 int i, j, k;
1584 SchroFrameData *dcomp;
1585 SchroFrameData *scomp;
1586
1587 if (SCHRO_FRAME_FORMAT_DEPTH (dest->format) != SCHRO_FRAME_FORMAT_DEPTH_U8 ||
1588 SCHRO_FRAME_FORMAT_DEPTH (src->format) != SCHRO_FRAME_FORMAT_DEPTH_U8 ||
1589 src->format != dest->format) {
1590 SCHRO_ERROR ("unimplemented");
1591 return;
1592 }
1593
1594 for (k = 0; k < 3; k++) {
1595 static const int16_t taps[8] = { -1, 3, -7, 21, 21, -7, 3, -1 };
1596 uint8_t *list[8];
1597
1598 dcomp = &dest->components[k];
1599 scomp = &src->components[k];
1600
1601 for (j = 0; j < dcomp->height - 1; j++) {
1602 if (j < 3 || j >= scomp->height - 4) {
1603 for (i = 0; i < 8; i++) {
1604 list[i] = SCHRO_FRAME_DATA_GET_LINE (scomp,
1605 CLAMP (i + j - 3, 0, scomp->height - 1));
1606 }
1607 mas8_across_u8_slow (SCHRO_FRAME_DATA_GET_LINE (dcomp, j), list,
1608 taps, 16, 5, scomp->width);
1609 } else {
1610 SCHRO_ASSERT (j - 3 >= 0);
1611 SCHRO_ASSERT (j - 3 + 7 < scomp->height);
1612 mas8_across_u8 (SCHRO_FRAME_DATA_GET_LINE (dcomp, j),
1613 SCHRO_FRAME_DATA_GET_LINE (scomp, j - 3), scomp->stride,
1614 taps, 16, 5, scomp->width);
1615 }
1616 }
1617 j = dcomp->height - 1;
1618 orc_memcpy (SCHRO_FRAME_DATA_GET_LINE (dcomp, j),
1619 SCHRO_FRAME_DATA_GET_LINE (scomp, j), dcomp->width);
1620 }
1621 }
1622
1623 double
schro_frame_calculate_average_luma(SchroFrame * frame)1624 schro_frame_calculate_average_luma (SchroFrame * frame)
1625 {
1626 SchroFrameData *comp;
1627 int j;
1628 int sum = 0;
1629 int n;
1630
1631 comp = &frame->components[0];
1632
1633 switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
1634 case SCHRO_FRAME_FORMAT_DEPTH_U8:
1635 for (j = 0; j < comp->height; j++) {
1636 int32_t linesum;
1637 orc_sum_u8 (&linesum, SCHRO_FRAME_DATA_GET_LINE (comp, j), comp->width);
1638 sum += linesum;
1639 }
1640 break;
1641 case SCHRO_FRAME_FORMAT_DEPTH_S16:
1642 for (j = 0; j < comp->height; j++) {
1643 int32_t linesum;
1644 orc_sum_s16 (&linesum, SCHRO_FRAME_DATA_GET_LINE (comp, j),
1645 comp->width);
1646 sum += linesum;
1647 }
1648 break;
1649 default:
1650 SCHRO_ERROR ("unimplemented");
1651 break;
1652 }
1653
1654 n = comp->height * comp->width;
1655 return (double) sum / n;
1656 }
1657
1658 SchroFrame *
schro_frame_convert_to_444(SchroFrame * frame)1659 schro_frame_convert_to_444 (SchroFrame * frame)
1660 {
1661 SchroFrame *dest;
1662
1663 SCHRO_ASSERT (frame->format == SCHRO_FRAME_FORMAT_U8_420);
1664
1665 dest = schro_frame_new_and_alloc (frame->domain, SCHRO_FRAME_FORMAT_U8_444,
1666 frame->width, frame->height);
1667
1668 schro_frame_convert (dest, frame);
1669
1670 return dest;
1671 }
1672
1673
1674 /* Copied from elsewhere */
1675 /*
1676 * This code implements the MD5 message-digest algorithm.
1677 * The algorithm is due to Ron Rivest. This code was
1678 * written by Colin Plumb in 1993, no copyright is claimed.
1679 * This code is in the public domain; do with it what you wish.
1680 *
1681 * Equivalent code is available from RSA Data Security, Inc.
1682 * This code has been tested against that, and is equivalent,
1683 * except that you don't need to include two pages of legalese
1684 * with every copy.
1685 *
1686 * To compute the message digest of a chunk of bytes, declare an
1687 * MD5Context structure, pass it to MD5Init, call MD5Update as
1688 * needed on buffers full of bytes, and then call MD5Final, which
1689 * will fill a supplied 16-byte array with the digest.
1690 */
1691
1692 #ifdef WORDS_BIGENDIAN
1693 #define uint32_to_host(a) \
1694 ((((a)&0xff)<<24)|(((a)&0xff00)<<8)|(((a)&0xff0000)>>8)|(((a)>>24)&0xff))
1695 #else
1696 #define uint32_to_host(a) (a)
1697 #endif
1698
1699 #define F1(x, y, z) (z ^ (x & (y ^ z)))
1700 #define F2(x, y, z) F1(z, x, y)
1701 #define F3(x, y, z) (x ^ y ^ z)
1702 #define F4(x, y, z) (y ^ (x | ~z))
1703
1704 #define MD5STEP(f,w,x,y,z,in,offset,s) \
1705 (w += f(x,y,z) + uint32_to_host(in) + offset, w = (w<<s | w>>(32-s)) + x)
1706
1707 static void
schro_md5(uint32_t * state,uint32_t * src)1708 schro_md5 (uint32_t * state, uint32_t * src)
1709 {
1710 uint32_t a, b, c, d;
1711
1712 a = state[0];
1713 b = state[1];
1714 c = state[2];
1715 d = state[3];
1716
1717 MD5STEP (F1, a, b, c, d, src[0], 0xd76aa478, 7);
1718 MD5STEP (F1, d, a, b, c, src[1], 0xe8c7b756, 12);
1719 MD5STEP (F1, c, d, a, b, src[2], 0x242070db, 17);
1720 MD5STEP (F1, b, c, d, a, src[3], 0xc1bdceee, 22);
1721 MD5STEP (F1, a, b, c, d, src[4], 0xf57c0faf, 7);
1722 MD5STEP (F1, d, a, b, c, src[5], 0x4787c62a, 12);
1723 MD5STEP (F1, c, d, a, b, src[6], 0xa8304613, 17);
1724 MD5STEP (F1, b, c, d, a, src[7], 0xfd469501, 22);
1725 MD5STEP (F1, a, b, c, d, src[8], 0x698098d8, 7);
1726 MD5STEP (F1, d, a, b, c, src[9], 0x8b44f7af, 12);
1727 MD5STEP (F1, c, d, a, b, src[10], 0xffff5bb1, 17);
1728 MD5STEP (F1, b, c, d, a, src[11], 0x895cd7be, 22);
1729 MD5STEP (F1, a, b, c, d, src[12], 0x6b901122, 7);
1730 MD5STEP (F1, d, a, b, c, src[13], 0xfd987193, 12);
1731 MD5STEP (F1, c, d, a, b, src[14], 0xa679438e, 17);
1732 MD5STEP (F1, b, c, d, a, src[15], 0x49b40821, 22);
1733
1734 MD5STEP (F2, a, b, c, d, src[1], 0xf61e2562, 5);
1735 MD5STEP (F2, d, a, b, c, src[6], 0xc040b340, 9);
1736 MD5STEP (F2, c, d, a, b, src[11], 0x265e5a51, 14);
1737 MD5STEP (F2, b, c, d, a, src[0], 0xe9b6c7aa, 20);
1738 MD5STEP (F2, a, b, c, d, src[5], 0xd62f105d, 5);
1739 MD5STEP (F2, d, a, b, c, src[10], 0x02441453, 9);
1740 MD5STEP (F2, c, d, a, b, src[15], 0xd8a1e681, 14);
1741 MD5STEP (F2, b, c, d, a, src[4], 0xe7d3fbc8, 20);
1742 MD5STEP (F2, a, b, c, d, src[9], 0x21e1cde6, 5);
1743 MD5STEP (F2, d, a, b, c, src[14], 0xc33707d6, 9);
1744 MD5STEP (F2, c, d, a, b, src[3], 0xf4d50d87, 14);
1745 MD5STEP (F2, b, c, d, a, src[8], 0x455a14ed, 20);
1746 MD5STEP (F2, a, b, c, d, src[13], 0xa9e3e905, 5);
1747 MD5STEP (F2, d, a, b, c, src[2], 0xfcefa3f8, 9);
1748 MD5STEP (F2, c, d, a, b, src[7], 0x676f02d9, 14);
1749 MD5STEP (F2, b, c, d, a, src[12], 0x8d2a4c8a, 20);
1750
1751 MD5STEP (F3, a, b, c, d, src[5], 0xfffa3942, 4);
1752 MD5STEP (F3, d, a, b, c, src[8], 0x8771f681, 11);
1753 MD5STEP (F3, c, d, a, b, src[11], 0x6d9d6122, 16);
1754 MD5STEP (F3, b, c, d, a, src[14], 0xfde5380c, 23);
1755 MD5STEP (F3, a, b, c, d, src[1], 0xa4beea44, 4);
1756 MD5STEP (F3, d, a, b, c, src[4], 0x4bdecfa9, 11);
1757 MD5STEP (F3, c, d, a, b, src[7], 0xf6bb4b60, 16);
1758 MD5STEP (F3, b, c, d, a, src[10], 0xbebfbc70, 23);
1759 MD5STEP (F3, a, b, c, d, src[13], 0x289b7ec6, 4);
1760 MD5STEP (F3, d, a, b, c, src[0], 0xeaa127fa, 11);
1761 MD5STEP (F3, c, d, a, b, src[3], 0xd4ef3085, 16);
1762 MD5STEP (F3, b, c, d, a, src[6], 0x04881d05, 23);
1763 MD5STEP (F3, a, b, c, d, src[9], 0xd9d4d039, 4);
1764 MD5STEP (F3, d, a, b, c, src[12], 0xe6db99e5, 11);
1765 MD5STEP (F3, c, d, a, b, src[15], 0x1fa27cf8, 16);
1766 MD5STEP (F3, b, c, d, a, src[2], 0xc4ac5665, 23);
1767
1768 MD5STEP (F4, a, b, c, d, src[0], 0xf4292244, 6);
1769 MD5STEP (F4, d, a, b, c, src[7], 0x432aff97, 10);
1770 MD5STEP (F4, c, d, a, b, src[14], 0xab9423a7, 15);
1771 MD5STEP (F4, b, c, d, a, src[5], 0xfc93a039, 21);
1772 MD5STEP (F4, a, b, c, d, src[12], 0x655b59c3, 6);
1773 MD5STEP (F4, d, a, b, c, src[3], 0x8f0ccc92, 10);
1774 MD5STEP (F4, c, d, a, b, src[10], 0xffeff47d, 15);
1775 MD5STEP (F4, b, c, d, a, src[1], 0x85845dd1, 21);
1776 MD5STEP (F4, a, b, c, d, src[8], 0x6fa87e4f, 6);
1777 MD5STEP (F4, d, a, b, c, src[15], 0xfe2ce6e0, 10);
1778 MD5STEP (F4, c, d, a, b, src[6], 0xa3014314, 15);
1779 MD5STEP (F4, b, c, d, a, src[13], 0x4e0811a1, 21);
1780 MD5STEP (F4, a, b, c, d, src[4], 0xf7537e82, 6);
1781 MD5STEP (F4, d, a, b, c, src[11], 0xbd3af235, 10);
1782 MD5STEP (F4, c, d, a, b, src[2], 0x2ad7d2bb, 15);
1783 MD5STEP (F4, b, c, d, a, src[9], 0xeb86d391, 21);
1784
1785 state[0] += a;
1786 state[1] += b;
1787 state[2] += c;
1788 state[3] += d;
1789 }
1790
1791 /* END Copied from elsewhere */
1792
1793
1794 void
schro_frame_md5(SchroFrame * frame,uint32_t * state)1795 schro_frame_md5 (SchroFrame * frame, uint32_t * state)
1796 {
1797 uint8_t *line;
1798 int x, y, k;
1799
1800 state[0] = 0x67452301;
1801 state[1] = 0xefcdab89;
1802 state[2] = 0x98badcfe;
1803 state[3] = 0x10325476;
1804
1805 x = 0;
1806 y = 0;
1807 k = 0;
1808 for (k = 0; k < 3; k++) {
1809 for (y = 0; y < frame->components[k].height; y++) {
1810 line = SCHRO_FRAME_DATA_GET_LINE (&frame->components[k], y);
1811 for (x = 0; x + 63 < frame->components[k].width; x += 64) {
1812 schro_md5 (state, (uint32_t *) (line + x));
1813 }
1814 if (x < frame->components[k].width) {
1815 uint8_t tmp[64];
1816 int left;
1817 left = frame->components[k].width - x;
1818 memcpy (tmp, line + x, left);
1819 memset (tmp + left, 0, 64 - left);
1820 schro_md5 (state, (uint32_t *) tmp);
1821 }
1822 }
1823 }
1824
1825 state[0] = uint32_to_host(state[0]);
1826 state[1] = uint32_to_host(state[1]);
1827 state[2] = uint32_to_host(state[2]);
1828 state[3] = uint32_to_host(state[3]);
1829
1830 SCHRO_DEBUG
1831 ("md5 %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
1832 state[0] & 0xff, (state[0] >> 8) & 0xff, (state[0] >> 16) & 0xff,
1833 (state[0] >> 24) & 0xff, state[1] & 0xff, (state[1] >> 8) & 0xff,
1834 (state[1] >> 16) & 0xff, (state[1] >> 24) & 0xff, state[2] & 0xff,
1835 (state[2] >> 8) & 0xff, (state[2] >> 16) & 0xff, (state[2] >> 24) & 0xff,
1836 state[3] & 0xff, (state[3] >> 8) & 0xff, (state[3] >> 16) & 0xff,
1837 (state[3] >> 24) & 0xff);
1838 }
1839
1840 void
schro_frame_data_get_codeblock(SchroFrameData * dest,SchroFrameData * src,int x,int y,int horiz_codeblocks,int vert_codeblocks)1841 schro_frame_data_get_codeblock (SchroFrameData * dest, SchroFrameData * src,
1842 int x, int y, int horiz_codeblocks, int vert_codeblocks)
1843 {
1844 int xmin = (src->width * x) / horiz_codeblocks;
1845 int xmax = (src->width * (x + 1)) / horiz_codeblocks;
1846 int ymin = (src->height * y) / vert_codeblocks;
1847 int ymax = (src->height * (y + 1)) / vert_codeblocks;
1848
1849 dest->format = src->format;
1850 if (SCHRO_FRAME_FORMAT_DEPTH (src->format) ==
1851 SCHRO_FRAME_FORMAT_DEPTH_S32) {
1852 dest->data = SCHRO_FRAME_DATA_GET_PIXEL_S32 (src, xmin, ymin);
1853 } else {
1854 dest->data = SCHRO_FRAME_DATA_GET_PIXEL_S16 (src, xmin, ymin);
1855 }
1856 dest->stride = src->stride;
1857 dest->width = xmax - xmin;
1858 dest->height = ymax - ymin;
1859 dest->length = 0;
1860 dest->h_shift = src->h_shift;
1861 dest->v_shift = src->v_shift;
1862 }
1863
1864 void
schro_frame_split_fields(SchroFrame * dest1,SchroFrame * dest2,SchroFrame * src)1865 schro_frame_split_fields (SchroFrame * dest1, SchroFrame * dest2,
1866 SchroFrame * src)
1867 {
1868 SchroFrame src_tmp;
1869
1870 SCHRO_ASSERT ((src->height & 1) == 0);
1871
1872 memcpy (&src_tmp, src, sizeof (src_tmp));
1873
1874 src_tmp.height = src->height / 2;
1875 src_tmp.components[0].stride *= 2;
1876 src_tmp.components[1].stride *= 2;
1877 src_tmp.components[2].stride *= 2;
1878
1879 schro_frame_convert (dest1, &src_tmp);
1880
1881 src_tmp.components[0].data =
1882 SCHRO_FRAME_DATA_GET_LINE (&src->components[0], 1);
1883 src_tmp.components[1].data =
1884 SCHRO_FRAME_DATA_GET_LINE (&src->components[1], 1);
1885 src_tmp.components[2].data =
1886 SCHRO_FRAME_DATA_GET_LINE (&src->components[2], 1);
1887
1888 schro_frame_convert (dest2, &src_tmp);
1889 }
1890
1891 /* upsampled frame */
1892
1893 SchroUpsampledFrame *
schro_upsampled_frame_new(SchroFrame * frame)1894 schro_upsampled_frame_new (SchroFrame * frame)
1895 {
1896 SchroUpsampledFrame *df;
1897
1898 df = schro_malloc0 (sizeof (SchroUpsampledFrame));
1899
1900 SCHRO_ASSERT (frame->is_upsampled);
1901 df->frames[0] = frame;
1902
1903 return df;
1904 }
1905
1906 void
schro_upsampled_frame_free(SchroUpsampledFrame * df)1907 schro_upsampled_frame_free (SchroUpsampledFrame * df)
1908 {
1909 int i;
1910 for (i = 0; i < 4; i++) {
1911 if (df->frames[i]) {
1912 schro_frame_unref (df->frames[i]);
1913 }
1914 }
1915 schro_free (df);
1916 }
1917
1918 static void
schro_frame_mc_edgeextend_horiz(SchroFrame * frame,SchroFrame * src)1919 schro_frame_mc_edgeextend_horiz (SchroFrame * frame, SchroFrame * src)
1920 {
1921 int k;
1922 int j;
1923
1924 for (k = 0; k < 3; k++) {
1925 int width = frame->components[k].width;
1926
1927 for (j = 0; j < frame->components[k].height; j++) {
1928 uint8_t *line = SCHRO_FRAME_DATA_GET_LINE (frame->components + k, j);
1929 uint8_t *src_line = SCHRO_FRAME_DATA_GET_LINE (src->components + k, j);
1930
1931 memset (line - frame->extension, src_line[0], frame->extension);
1932 /* A picture of size (w,h) is upconverted to (2*w-1,2*h-1)
1933 * However, schroedinger's effective upconverted size is (2*w,2*h)
1934 * Remember to overwrite the last horizontal pel */
1935 memset (line + width - 1, src_line[width - 1], frame->extension + 1);
1936 }
1937 }
1938 }
1939
1940 static void
schro_frame_mc_edgeextend_vert(SchroFrame * frame,SchroFrame * src)1941 schro_frame_mc_edgeextend_vert (SchroFrame * frame, SchroFrame * src)
1942 {
1943 int k;
1944 int j;
1945
1946 for (k = 0; k < 3; k++) {
1947 int height = frame->components[k].height;
1948 int width = frame->components[k].width;
1949
1950 for (j = 0; j < frame->extension; j++) {
1951 orc_memcpy (SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (frame->components +
1952 k, -j - 1), -frame->extension),
1953 SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (src->components + k, 0),
1954 -frame->extension), width + frame->extension * 2);
1955 orc_memcpy (SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (frame->components +
1956 k, height + j), -frame->extension),
1957 SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (src->components + k,
1958 height - 1), -frame->extension),
1959 width + frame->extension * 2);
1960 }
1961 /* A picture of size (w,h) is upconverted to (2*w-1,2*h-1)
1962 * However, schroedinger's effective upconverted size is (2*w,2*h)
1963 * Copy the src into the bottom line of frame.
1964 * NB, this assumes that orc_memcpy is safe when src == dest */
1965 orc_memcpy (SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (frame->components + k,
1966 height - 1), -frame->extension),
1967 SCHRO_OFFSET (SCHRO_FRAME_DATA_GET_LINE (src->components + k,
1968 height - 1), -frame->extension), width + frame->extension * 2);
1969 }
1970 }
1971
1972 void
schro_frame_mc_edgeextend(SchroFrame * frame)1973 schro_frame_mc_edgeextend (SchroFrame * frame)
1974 {
1975 schro_frame_mc_edgeextend_horiz (frame, frame);
1976 schro_frame_mc_edgeextend_vert (frame, frame);
1977 }
1978
1979
1980 void
schro_upsampled_frame_upsample(SchroUpsampledFrame * df)1981 schro_upsampled_frame_upsample (SchroUpsampledFrame * df)
1982 {
1983 int i;
1984
1985 if (df->frames[1])
1986 return;
1987
1988 for (i=1;i<4;i++){
1989 df->frames[i] = schro_frame_new();
1990 df->frames[i]->format = df->frames[0]->format;
1991 df->frames[i]->width = df->frames[0]->width;
1992 df->frames[i]->height = df->frames[0]->height;
1993 df->frames[i]->extension = df->frames[0]->extension;
1994 memcpy (df->frames[i]->components, df->frames[0]->components,
1995 sizeof (SchroFrameData) * 3);
1996 df->frames[i]->components[0].data +=
1997 (df->frames[i]->components[0].stride >> 2) * i;
1998 df->frames[i]->components[1].data +=
1999 (df->frames[i]->components[1].stride >> 2) * i;
2000 df->frames[i]->components[2].data +=
2001 (df->frames[i]->components[2].stride >> 2) * i;
2002 }
2003
2004 schro_frame_upsample_vert (df->frames[2], df->frames[0]);
2005 schro_frame_mc_edgeextend_horiz (df->frames[2], df->frames[2]);
2006 schro_frame_mc_edgeextend_vert (df->frames[2], df->frames[0]);
2007
2008 schro_frame_upsample_horiz (df->frames[1], df->frames[0]);
2009 schro_frame_mc_edgeextend_horiz (df->frames[1], df->frames[0]);
2010 schro_frame_mc_edgeextend_vert (df->frames[1], df->frames[1]);
2011
2012 schro_frame_upsample_horiz (df->frames[3], df->frames[2]);
2013 schro_frame_mc_edgeextend_horiz (df->frames[3], df->frames[2]);
2014 schro_frame_mc_edgeextend_vert (df->frames[3], df->frames[1]);
2015 }
2016
2017 #ifdef ENABLE_MOTION_REF
2018 int
schro_upsampled_frame_get_pixel_prec0(SchroUpsampledFrame * upframe,int k,int x,int y)2019 schro_upsampled_frame_get_pixel_prec0 (SchroUpsampledFrame * upframe, int k,
2020 int x, int y)
2021 {
2022 SchroFrameData *comp;
2023 uint8_t *line;
2024
2025 comp = upframe->frames[0]->components + k;
2026 x = CLAMP (x, 0, comp->width - 1);
2027 y = CLAMP (y, 0, comp->height - 1);
2028
2029 line = SCHRO_FRAME_DATA_GET_LINE (comp, y);
2030
2031 return line[x];
2032 }
2033
2034 int
schro_frame_get_data(SchroFrame * frame,SchroFrameData * fd,int k,int x,int y)2035 schro_frame_get_data (SchroFrame * frame, SchroFrameData * fd, int k, int x,
2036 int y)
2037 {
2038 SchroFrameData *comp = frame->components + k;
2039
2040 SCHRO_ASSERT (frame && fd && !(0 > x) && !(0 > y));
2041 /* check whether the required block lies completely outside the frame */
2042 if (!(frame->width > x) || !(frame->height > y)) {
2043 return FALSE;
2044 }
2045 SCHRO_ASSERT (SCHRO_FRAME_FORMAT_DEPTH (comp->format) ==
2046 SCHRO_FRAME_FORMAT_DEPTH_U8);
2047
2048 fd->format = comp->format;
2049 fd->data = SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, x, y);
2050 fd->stride = comp->stride;
2051 fd->width = comp->width - x;
2052 fd->height = comp->height - y;
2053 fd->h_shift = comp->h_shift;
2054 fd->v_shift = comp->v_shift;
2055
2056 return TRUE;
2057 }
2058
2059 #ifdef unused
2060 void
schro_upsampled_frame_get_block_prec0(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2061 schro_upsampled_frame_get_block_prec0 (SchroUpsampledFrame * upframe, int k,
2062 int x, int y, SchroFrameData * fd)
2063 {
2064 int i, j;
2065 uint8_t *data;
2066
2067 for (j = 0; j < fd->height; j++) {
2068 data = SCHRO_FRAME_DATA_GET_LINE (fd, j);
2069 for (i = 0; i < fd->width; i++) {
2070 data[i] = schro_upsampled_frame_get_pixel_prec0 (upframe, k,
2071 x + i, y + j);
2072 }
2073 }
2074 }
2075 #endif
2076 #endif
2077
2078 #ifdef unused
2079 void
schro_upsampled_frame_get_block_fast_prec0(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2080 schro_upsampled_frame_get_block_fast_prec0 (SchroUpsampledFrame * upframe,
2081 int k, int x, int y, SchroFrameData * fd)
2082 {
2083 SchroFrameData *comp;
2084 int j;
2085
2086 comp = upframe->frames[0]->components + k;
2087
2088 for (j = 0; j < fd->height; j++) {
2089 uint8_t *dest = SCHRO_FRAME_DATA_GET_LINE (fd, j);
2090 uint8_t *src = SCHRO_FRAME_DATA_GET_LINE (comp, y + j);
2091 memcpy (dest, src + x, fd->width);
2092 }
2093 }
2094 #endif
2095
2096 void
schro_upsampled_frame_get_subdata_prec0(SchroUpsampledFrame * upframe,int component,int x,int y,SchroFrameData * fd)2097 schro_upsampled_frame_get_subdata_prec0 (SchroUpsampledFrame * upframe,
2098 int component, int x, int y, SchroFrameData * fd)
2099 {
2100 SchroFrameData *comp = upframe->frames[0]->components + component;
2101
2102 fd->data = SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, x, y);
2103 fd->stride = comp->stride;
2104 }
2105
2106 #ifdef ENABLE_MOTION_REF
2107 int
schro_upsampled_frame_get_pixel_prec1(SchroUpsampledFrame * upframe,int k,int x,int y)2108 schro_upsampled_frame_get_pixel_prec1 (SchroUpsampledFrame * upframe, int k,
2109 int x, int y)
2110 {
2111 SchroFrameData *comp;
2112 uint8_t *line;
2113 int i;
2114
2115 comp = upframe->frames[0]->components + k;
2116 x = CLAMP (x, 0, comp->width * 2 - 2);
2117 y = CLAMP (y, 0, comp->height * 2 - 2);
2118
2119 i = ((y & 1) << 1) | (x & 1);
2120 x >>= 1;
2121 y >>= 1;
2122
2123 comp = upframe->frames[i]->components + k;
2124 line = SCHRO_FRAME_DATA_GET_LINE (comp, y);
2125
2126 return line[x];
2127 }
2128
2129 #ifdef unused
2130 void
schro_upsampled_frame_get_block_prec1(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2131 schro_upsampled_frame_get_block_prec1 (SchroUpsampledFrame * upframe, int k,
2132 int x, int y, SchroFrameData * fd)
2133 {
2134 int i, j;
2135 uint8_t *data;
2136
2137 for (j = 0; j < fd->height; j++) {
2138 data = SCHRO_FRAME_DATA_GET_LINE (fd, j);
2139 for (i = 0; i < fd->width; i++) {
2140 data[i] = schro_upsampled_frame_get_pixel_prec1 (upframe, k,
2141 x + (i << 1), y + (j << 1));
2142 }
2143 }
2144 }
2145 #endif
2146 #endif
2147
2148 static void
schro_upsampled_frame_get_block_fast_prec1(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2149 schro_upsampled_frame_get_block_fast_prec1 (SchroUpsampledFrame * upframe,
2150 int k, int x, int y, SchroFrameData * fd)
2151 {
2152 SchroFrameData *comp;
2153 int i;
2154 int j;
2155
2156 i = ((y & 1) << 1) | (x & 1);
2157 x >>= 1;
2158 y >>= 1;
2159
2160 comp = upframe->frames[i]->components + k;
2161 for (j = 0; j < fd->height; j++) {
2162 uint8_t *dest = SCHRO_FRAME_DATA_GET_LINE (fd, j);
2163 uint8_t *src = SCHRO_FRAME_DATA_GET_LINE (comp, y + j);
2164 orc_memcpy (dest, src + x, fd->width);
2165 }
2166 }
2167
2168 static void
__schro_upsampled_frame_get_subdata_prec1(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2169 __schro_upsampled_frame_get_subdata_prec1 (SchroUpsampledFrame * upframe,
2170 int k, int x, int y, SchroFrameData * fd)
2171 {
2172 SchroFrameData *comp;
2173 int i;
2174
2175 i = ((y & 1) << 1) | (x & 1);
2176 x >>= 1;
2177 y >>= 1;
2178
2179 comp = upframe->frames[i]->components + k;
2180 fd->data = SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, x, y);
2181 fd->stride = comp->stride;
2182 }
2183
2184 void
schro_upsampled_frame_get_subdata_prec1(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2185 schro_upsampled_frame_get_subdata_prec1 (SchroUpsampledFrame * upframe,
2186 int k, int x, int y, SchroFrameData * fd)
2187 {
2188 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, x, y, fd);
2189 }
2190
2191 #ifdef ENABLE_MOTION_REF
2192 int
schro_upsampled_frame_get_pixel_prec3(SchroUpsampledFrame * upframe,int k,int x,int y)2193 schro_upsampled_frame_get_pixel_prec3 (SchroUpsampledFrame * upframe, int k,
2194 int x, int y)
2195 {
2196 int hx, hy;
2197 int rx, ry;
2198 int w00, w01, w10, w11;
2199 int value;
2200
2201 hx = x >> 2;
2202 hy = y >> 2;
2203
2204 rx = x & 0x3;
2205 ry = y & 0x3;
2206
2207 w00 = (4 - ry) * (4 - rx);
2208 w01 = (4 - ry) * rx;
2209 w10 = ry * (4 - rx);
2210 w11 = ry * rx;
2211
2212 if (hx >= 0 && hx < 2 * upframe->frames[0]->components[k].width - 2 &&
2213 hy >= 0 && hy < 2 * upframe->frames[0]->components[k].height - 2) {
2214 SchroFrameData *comp;
2215 int p;
2216 int i;
2217
2218 i = ((hy & 1) << 1) | (hx & 1);
2219
2220 comp = upframe->frames[i]->components + k;
2221 p = *SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, hx >> 1, hy >> 1);
2222 value = w00 * p;
2223
2224 comp = upframe->frames[i ^ 1]->components + k;
2225 p = *SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, (hx + 1) >> 1, hy >> 1);
2226 value += w01 * p;
2227
2228 comp = upframe->frames[i ^ 2]->components + k;
2229 p = *SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, hx >> 1, (hy + 1) >> 1);
2230 value += w10 * p;
2231
2232 comp = upframe->frames[i ^ 3]->components + k;
2233 p = *SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, (hx + 1) >> 1, (hy + 1) >> 1);
2234 value += w11 * p;
2235 } else {
2236 value = w00 * schro_upsampled_frame_get_pixel_prec1 (upframe, k, hx, hy);
2237 value +=
2238 w01 * schro_upsampled_frame_get_pixel_prec1 (upframe, k, hx + 1, hy);
2239 value +=
2240 w10 * schro_upsampled_frame_get_pixel_prec1 (upframe, k, hx, hy + 1);
2241 value +=
2242 w11 * schro_upsampled_frame_get_pixel_prec1 (upframe, k, hx + 1,
2243 hy + 1);
2244 }
2245
2246 return ROUND_SHIFT (value, 4);
2247 }
2248
2249 #ifdef unused
2250 void
schro_upsampled_frame_get_block_prec3(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2251 schro_upsampled_frame_get_block_prec3 (SchroUpsampledFrame * upframe, int k,
2252 int x, int y, SchroFrameData * fd)
2253 {
2254 int i, j;
2255 uint8_t *data;
2256
2257 for (j = 0; j < fd->height; j++) {
2258 data = SCHRO_FRAME_DATA_GET_LINE (fd, j);
2259 for (i = 0; i < fd->width; i++) {
2260 data[i] = schro_upsampled_frame_get_pixel_prec3 (upframe, k,
2261 x + (i << 3), y + (j << 3));
2262 }
2263 }
2264 }
2265 #endif
2266 #endif
2267
2268 static void
schro_upsampled_frame_get_block_fast_prec3(SchroUpsampledFrame * upframe,int k,int x,int y,SchroFrameData * fd)2269 schro_upsampled_frame_get_block_fast_prec3 (SchroUpsampledFrame * upframe,
2270 int k, int x, int y, SchroFrameData * fd)
2271 {
2272 int hx, hy;
2273 int rx, ry;
2274 int w00, w01, w10, w11;
2275 SchroFrameData fd00;
2276 SchroFrameData fd01;
2277 SchroFrameData fd10;
2278 SchroFrameData fd11;
2279
2280 hx = x >> 2;
2281 hy = y >> 2;
2282
2283 rx = x & 0x3;
2284 ry = y & 0x3;
2285
2286 switch ((ry << 2) | rx) {
2287 case 0:
2288 schro_upsampled_frame_get_block_fast_prec1 (upframe, k, hx, hy, fd);
2289 break;
2290 case 2:
2291 case 8:
2292 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx, hy, &fd00);
2293 if (rx == 0) {
2294 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx, hy + 1,
2295 &fd10);
2296 } else {
2297 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx + 1, hy,
2298 &fd10);
2299 }
2300
2301 switch (fd->width) {
2302 case 8:
2303 orc_avg2_8xn_u8 (fd->data, fd->stride,
2304 fd00.data, fd00.stride, fd10.data, fd10.stride, fd->height);
2305 break;
2306 case 12:
2307 orc_avg2_12xn_u8 (fd->data, fd->stride,
2308 fd00.data, fd00.stride, fd10.data, fd10.stride, fd->height);
2309 break;
2310 case 16:
2311 orc_avg2_16xn_u8 (fd->data, fd->stride,
2312 fd00.data, fd00.stride, fd10.data, fd10.stride, fd->height);
2313 break;
2314 case 24:
2315 orc_avg2_16xn_u8 (fd->data, fd->stride,
2316 fd00.data, fd00.stride, fd10.data, fd10.stride, fd->height);
2317 orc_avg2_8xn_u8 (SCHRO_OFFSET (fd->data, 16), fd->stride,
2318 SCHRO_OFFSET (fd00.data, 16), fd00.stride,
2319 SCHRO_OFFSET (fd10.data, 16), fd10.stride, fd->height);
2320 break;
2321 case 32:
2322 orc_avg2_32xn_u8 (fd->data, fd->stride,
2323 fd00.data, fd00.stride, fd10.data, fd10.stride, fd->height);
2324 break;
2325 default:
2326 orc_avg2_nxm_u8 (fd->data, fd->stride,
2327 fd00.data, fd00.stride, fd10.data, fd10.stride,
2328 fd->width, fd->height);
2329 break;
2330 }
2331 break;
2332 default:
2333 w00 = (4 - ry) * (4 - rx);
2334 w01 = (4 - ry) * rx;
2335 w10 = ry * (4 - rx);
2336 w11 = ry * rx;
2337
2338 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx, hy, &fd00);
2339 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx + 1, hy, &fd01);
2340 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx, hy + 1, &fd10);
2341 __schro_upsampled_frame_get_subdata_prec1 (upframe, k, hx + 1, hy + 1,
2342 &fd11);
2343
2344 switch (fd->width) {
2345 #if 0
2346 case 8:
2347 orc_combine4_8xn_u8 (fd->data, fd->stride,
2348 fd00.data, fd00.stride,
2349 fd01.data, fd01.stride,
2350 fd10.data, fd10.stride,
2351 fd11.data, fd11.stride, w00, w01, w10, w11, fd->height);
2352 break;
2353 case 12:
2354 orc_combine4_12xn_u8 (fd->data, fd->stride,
2355 fd00.data, fd00.stride,
2356 fd01.data, fd01.stride,
2357 fd10.data, fd10.stride,
2358 fd11.data, fd11.stride, w00, w01, w10, w11, fd->height);
2359 break;
2360 case 16:
2361 orc_combine4_16xn_u8 (fd->data, fd->stride,
2362 fd00.data, fd00.stride,
2363 fd01.data, fd01.stride,
2364 fd10.data, fd10.stride,
2365 fd11.data, fd11.stride, w00, w01, w10, w11, fd->height);
2366 break;
2367 case 24:
2368 orc_combine4_24xn_u8 (fd->data, fd->stride,
2369 fd00.data, fd00.stride,
2370 fd01.data, fd01.stride,
2371 fd10.data, fd10.stride,
2372 fd11.data, fd11.stride, w00, w01, w10, w11, fd->height);
2373 break;
2374 case 32:
2375 orc_combine4_32xn_u8 (fd->data, fd->stride,
2376 fd00.data, fd00.stride,
2377 fd01.data, fd01.stride,
2378 fd10.data, fd10.stride,
2379 fd11.data, fd11.stride, w00, w01, w10, w11, fd->height);
2380 break;
2381 #endif
2382 default:
2383 orc_combine4_nxm_u8 (fd->data, fd->stride,
2384 fd00.data, fd00.stride,
2385 fd01.data, fd01.stride,
2386 fd10.data, fd10.stride,
2387 fd11.data, fd11.stride,
2388 w00, w01, w10, w11, fd->width, fd->height);
2389 break;
2390 }
2391 break;
2392 }
2393 }
2394
2395 #ifdef ENABLE_MOTION_REF
2396 int
schro_upsampled_frame_get_pixel_precN(SchroUpsampledFrame * upframe,int k,int x,int y,int prec)2397 schro_upsampled_frame_get_pixel_precN (SchroUpsampledFrame * upframe, int k,
2398 int x, int y, int prec)
2399 {
2400 switch (prec) {
2401 case 0:
2402 return schro_upsampled_frame_get_pixel_prec0 (upframe, k, x, y);
2403 case 1:
2404 return schro_upsampled_frame_get_pixel_prec1 (upframe, k, x, y);
2405 case 2:
2406 return schro_upsampled_frame_get_pixel_prec3 (upframe, k, x << 1, y << 1);
2407 case 3:
2408 return schro_upsampled_frame_get_pixel_prec3 (upframe, k, x, y);
2409 default:
2410 SCHRO_ASSERT (0);
2411 }
2412 }
2413
2414 #ifdef unused
2415 void
schro_upsampled_frame_get_block_precN(SchroUpsampledFrame * upframe,int k,int x,int y,int prec,SchroFrameData * fd)2416 schro_upsampled_frame_get_block_precN (SchroUpsampledFrame * upframe, int k,
2417 int x, int y, int prec, SchroFrameData * fd)
2418 {
2419 switch (prec) {
2420 case 0:
2421 schro_upsampled_frame_get_block_prec0 (upframe, k, x, y, fd);
2422 return;
2423 case 1:
2424 schro_upsampled_frame_get_block_prec1 (upframe, k, x, y, fd);
2425 return;
2426 case 2:
2427 schro_upsampled_frame_get_block_prec3 (upframe, k, x << 1, y << 1, fd);
2428 return;
2429 case 3:
2430 schro_upsampled_frame_get_block_prec3 (upframe, k, x, y, fd);
2431 return;
2432 default:
2433 SCHRO_ASSERT (0);
2434 }
2435 }
2436 #endif
2437 #endif
2438
2439 void
schro_upsampled_frame_get_block_fast_precN(SchroUpsampledFrame * upframe,int k,int x,int y,int prec,SchroFrameData * dest,SchroFrameData * fd)2440 schro_upsampled_frame_get_block_fast_precN (SchroUpsampledFrame * upframe,
2441 int k, int x, int y, int prec, SchroFrameData * dest, SchroFrameData * fd)
2442 {
2443 switch (prec) {
2444 case 0:
2445 schro_upsampled_frame_get_subdata_prec0 (upframe, k, x, y, dest);
2446 return;
2447 case 1:
2448 schro_upsampled_frame_get_subdata_prec1 (upframe, k, x, y, dest);
2449 return;
2450 case 2:
2451 memcpy (dest, fd, sizeof (SchroFrameData));
2452 schro_upsampled_frame_get_block_fast_prec3 (upframe, k, x << 1, y << 1,
2453 dest);
2454 return;
2455 case 3:
2456 memcpy (dest, fd, sizeof (SchroFrameData));
2457 schro_upsampled_frame_get_block_fast_prec3 (upframe, k, x, y, dest);
2458 return;
2459 default:
2460 SCHRO_ASSERT (0);
2461 }
2462 }
2463
2464 void
schro_frame_get_subdata(SchroFrame * frame,SchroFrameData * fd,int component,int x,int y)2465 schro_frame_get_subdata (SchroFrame * frame, SchroFrameData * fd,
2466 int component, int x, int y)
2467 {
2468 SchroFrameData *comp = frame->components + component;
2469
2470 SCHRO_ASSERT (SCHRO_FRAME_FORMAT_DEPTH (comp->format) ==
2471 SCHRO_FRAME_FORMAT_DEPTH_U8);
2472
2473 fd->format = comp->format;
2474 fd->data = SCHRO_FRAME_DATA_GET_PIXEL_U8 (comp, x, y);
2475 fd->stride = comp->stride;
2476 fd->width = MAX (0, comp->width - x);
2477 fd->height = MAX (0, comp->height - y);
2478 fd->h_shift = comp->h_shift;
2479 fd->v_shift = comp->v_shift;
2480 }
2481
2482 void
schro_frame_get_reference_subdata(SchroFrame * frame,SchroFrameData * fd,int component,int x,int y)2483 schro_frame_get_reference_subdata (SchroFrame * frame, SchroFrameData * fd,
2484 int component, int x, int y)
2485 {
2486 SchroFrameData *comp = frame->components + component;
2487 int extension = frame->extension;
2488
2489 schro_frame_get_subdata (frame, fd, component, x, y);
2490 /* modify width and height to account for a reference block
2491 * that can be completely outside of a frame */
2492 fd->width = MAX (0, comp->width + extension - x);
2493 fd->height = MAX (0, comp->height + extension - y);
2494 }
2495
schro_frame_get_bit_depth(SchroFrame * frame)2496 int schro_frame_get_bit_depth (SchroFrame *frame)
2497 {
2498 if (frame->format == SCHRO_FRAME_FORMAT_v210) {
2499 return 10;
2500 }
2501 switch (SCHRO_FRAME_FORMAT_DEPTH(frame->format)) {
2502 case SCHRO_FRAME_FORMAT_DEPTH_U8:
2503 return 8;
2504 case SCHRO_FRAME_FORMAT_DEPTH_S16:
2505 return 16;
2506 case SCHRO_FRAME_FORMAT_DEPTH_S32:
2507 return 32;
2508 }
2509 return 0;
2510 }
2511
2512