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