Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/J2KHelper.cpp view on Meta::CPAN
// ==========================================================
// JPEG2000 helpers
//
// Design and implementation by
// - Hervé Drolon (drolon@infonie.fr)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
#include "FreeImage.h"
#include "Utilities.h"
#include "../LibOpenJPEG/openjpeg.h"
#include "J2KHelper.h"
// --------------------------------------------------------------------------
static OPJ_UINT64
_LengthProc(J2KFIO_t *fio) {
long start_pos = fio->io->tell_proc(fio->handle);
fio->io->seek_proc(fio->handle, 0, SEEK_END);
unsigned file_length = fio->io->tell_proc(fio->handle) - start_pos;
fio->io->seek_proc(fio->handle, start_pos, SEEK_SET);
return (OPJ_UINT64)file_length;
}
static OPJ_SIZE_T
_ReadProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
OPJ_SIZE_T l_nb_read = fio->io->read_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
}
static OPJ_SIZE_T
_WriteProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
return fio->io->write_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
}
static OPJ_OFF_T
_SkipProc(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_CUR) ) {
return -1;
}
return p_nb_bytes;
}
static OPJ_BOOL
_SeekProc(OPJ_OFF_T p_nb_bytes, FILE * p_user_data) {
J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_SET) ) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
// --------------------------------------------------------------------------
J2KFIO_t*
opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, BOOL bRead) {
if(!handle) {
return NULL;
}
J2KFIO_t *fio = (J2KFIO_t*)malloc(sizeof(J2KFIO_t));
if(fio) {
fio->io = io;
fio->handle = handle;
opj_stream_t *l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, bRead ? OPJ_TRUE : OPJ_FALSE);
if (l_stream) {
opj_stream_set_user_data(l_stream, fio, NULL);
opj_stream_set_user_data_length(l_stream, _LengthProc(fio));
opj_stream_set_read_function(l_stream, (opj_stream_read_fn)_ReadProc);
opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_WriteProc);
opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn)_SkipProc);
opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn)_SeekProc);
fio->stream = l_stream;
return fio;
} else {
free(fio);
}
}
return NULL;
}
void
opj_freeimage_stream_destroy(J2KFIO_t* fio) {
if(fio) {
if(fio->stream) {
opj_stream_destroy(fio->stream);
}
free(fio);
}
}
// --------------------------------------------------------------------------
/**
Divide an integer by a power of 2 and round upwards
@return Returns a divided by 2^b
*/
static int int_ceildivpow2(int a, int b) {
return (a + (1 << b) - 1) >> b;
}
/**
Convert a OpenJPEG image to a FIBITMAP
@param format_id Plugin ID
@param image OpenJPEG image
@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
@return Returns the converted image if successful, returns NULL otherwise
*/
FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image, BOOL header_only) {
FIBITMAP *dib = NULL;
try {
// compute image width and height
//int w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
int wr = image->comps[0].w;
int wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
//int h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
//int hr = image->comps[0].h;
int hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
// check the number of components
int numcomps = image->numcomps;
BOOL bIsValid = TRUE;
( run in 0.434 second using v1.01-cache-2.11-cpan-119454b85a5 )