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