You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.4 KiB
120 lines
3.4 KiB
/*
|
|
* 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:
|
|
*/
|