1 /*
2  * imgconvert.c - image format conversion routines
3  * Written by Andrew Church <achurch@achurch.org>
4  *
5  * This file is part of transcode, a video stream processing tool.
6  * transcode is free software, distributable under the terms of the GNU
7  * General Public License (version 2 or later).  See the file COPYING
8  * for details.
9  */
10 
11 #include "ac.h"
12 #include "imgconvert.h"
13 #include "img_internal.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 /*************************************************************************/
19 
20 static struct {
21     ImageFormat srcfmt, destfmt;
22     ConversionFunc func;
23 } *conversions;
24 static int n_conversions = 0;
25 
26 /*************************************************************************/
27 /*************************************************************************/
28 
29 /* Image conversion routine.  src and dest are arrays of pointers to planes
30  * (for packed formats with only one plane, just use `&data'); srcfmt and
31  * destfmt specify the source and destination image formats (IMG_*).
32  * width and height are in pixels.  Returns 1 on success, 0 on failure. */
33 
ac_imgconvert(uint8_t ** src,ImageFormat srcfmt,uint8_t ** dest,ImageFormat destfmt,int width,int height)34 int ac_imgconvert(uint8_t **src, ImageFormat srcfmt,
35                   uint8_t **dest, ImageFormat destfmt,
36                   int width, int height)
37 {
38     int i;
39 
40     /* Hack to handle YV12 easily, because conversion routines don't get
41      * format tags */
42     uint8_t *newsrc[3], *newdest[3];
43     if (srcfmt == IMG_YV12) {
44         srcfmt = IMG_YUV420P;
45         newsrc[0] = src[0];
46         newsrc[1] = src[2];
47         newsrc[2] = src[1];
48         src = newsrc;
49     }
50     if (destfmt == IMG_YV12) {
51         destfmt = IMG_YUV420P;
52         newdest[0] = dest[0];
53         newdest[1] = dest[2];
54         newdest[2] = dest[1];
55         dest = newdest;
56     }
57 
58     for (i = 0; i < n_conversions; i++) {
59         if (conversions[i].srcfmt==srcfmt && conversions[i].destfmt==destfmt)
60             return (*conversions[i].func)(src, dest, width, height);
61     }
62 
63     return 0;
64 }
65 
66 /*************************************************************************/
67 /*************************************************************************/
68 
69 /* Internal use only! */
70 
ac_imgconvert_init(int accel)71 int ac_imgconvert_init(int accel)
72 {
73     if (!ac_imgconvert_init_yuv_planar(accel)
74      || !ac_imgconvert_init_yuv_packed(accel)
75      || !ac_imgconvert_init_yuv_mixed(accel)
76      || !ac_imgconvert_init_yuv_rgb(accel)
77      || !ac_imgconvert_init_rgb_packed(accel)
78     ) {
79         fprintf(stderr, "ac_imgconvert_init() failed");
80         return 0;
81     }
82     return 1;
83 }
84 
register_conversion(ImageFormat srcfmt,ImageFormat destfmt,ConversionFunc function)85 int register_conversion(ImageFormat srcfmt, ImageFormat destfmt,
86                         ConversionFunc function)
87 {
88     int i;
89 
90     for (i = 0; i < n_conversions; i++) {
91         if (conversions[i].srcfmt==srcfmt && conversions[i].destfmt==destfmt) {
92             conversions[i].func = function;
93             return 1;
94         }
95     }
96 
97     if (!(conversions = realloc(conversions,
98                                 (n_conversions+1) * sizeof(*conversions)))) {
99         fprintf(stderr, "register_conversion(): out of memory\n");
100         return 0;
101     }
102     conversions[n_conversions].srcfmt  = srcfmt;
103     conversions[n_conversions].destfmt = destfmt;
104     conversions[n_conversions].func    = function;
105     n_conversions++;
106     return 1;
107 }
108 
109 /*************************************************************************/
110 
111 /*
112  * Local variables:
113  *   c-file-style: "stroustrup"
114  *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
115  *   indent-tabs-mode: nil
116  * End:
117  *
118  * vim: expandtab shiftwidth=4:
119  */
120