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