blender/extern/libredcode/codec.c
Peter Schlaile 1c2ff55334 == libredcode / licence cleanup ==
Changed libredcode to GNU GPL v2 or later to make it more compatible
with additional libraries added to blender.
2013-07-14 20:38:55 +00:00

167 lines
4.0 KiB
C

/* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2008 Peter Schlaile
*
* This file is part of libredcode.
*
* Libredcode is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Libredcode is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libredcode; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****/
#include "codec.h"
#include "format.h"
#include "debayer.h"
#include <openjpeg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[R3D ERR] %s", msg);
}
static void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[R3D WARN] %s", msg);
}
static void info_callback(const char *msg, void *client_data)
{
(void)client_data;
fprintf(stdout, "[R3D INFO] %s", msg);
}
#define J2K_CFMT 0
#define JP2_CFMT 1
#define JPT_CFMT 2
struct redcode_frame_raw * redcode_decode_video_raw(
struct redcode_frame * frame, int scale)
{
struct redcode_frame_raw * rv = NULL;
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
opj_set_default_decoder_parameters(&parameters);
parameters.decod_format = JP2_CFMT;
if (scale == 2) {
parameters.cp_reduce = 1;
} else if (scale == 4) {
parameters.cp_reduce = 2;
} else if (scale == 8) {
parameters.cp_reduce = 3;
}
/* JPEG 2000 compressed image data */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_JP2);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using the current image
and user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo,
frame->data + frame->offset, frame->length);
image = opj_decode(dinfo, cio);
if(!image) {
fprintf(stderr,
"ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
return 0;
}
/* close the byte stream */
opj_cio_close(cio);
/* free remaining structures */
if(dinfo) {
opj_destroy_decompress(dinfo);
}
if((image->numcomps * image->x1 * image->y1) == 0) {
opj_image_destroy(image);
return 0;
}
rv = (struct redcode_frame_raw *) calloc(
1, sizeof(struct redcode_frame_raw));
rv->data = image;
rv->width = image->comps[0].w;
rv->height = image->comps[0].h;
return rv;
}
int redcode_decode_video_float(struct redcode_frame_raw * frame,
float * out, int scale)
{
int* planes[4];
int i;
opj_image_t *image = (opj_image_t*) frame->data;
if (image->numcomps != 4) {
fprintf(stderr, "R3D: need 4 planes, but got: %d\n",
image->numcomps);
return 0;
}
for (i = 0; i < 4; i++) {
planes[i] = image->comps[i].data;
}
if (scale == 1) {
redcode_ycbcr2rgb_fullscale(
planes, frame->width, frame->height, out);
} else if (scale == 2) {
redcode_ycbcr2rgb_halfscale(
planes, frame->width, frame->height, out);
} else if (scale == 4) {
redcode_ycbcr2rgb_quarterscale(
planes, frame->width, frame->height, out);
}
opj_image_destroy(image);
free(frame);
return 1;
}