123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /* GdkPixbuf library - JPEG2000 Image Loader
- *
- * Copyright © 2020 - 2024 Nichlas Severinsen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #ifndef UTIL_H
- #define UTIL_H
- #include <openjpeg.h>
- // The following defines and functions were copied from openjpeg.c
- // They are not included in libopenjp2 for whatever reason.
- // If they are ever included we should remove these and use them from libopenjp2 instead.
- #if defined(WIN32) && !defined(Windows95) && !defined(__BORLANDC__) && \
- !(defined(_MSC_VER) && _MSC_VER < 1400) && \
- !(defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x800)
- # define OPJ_FSEEK(stream, offset, whence) _fseeki64(stream, offset, whence)
- # define OPJ_FTELL(stream) _ftelli64(stream)
- #else
- # define OPJ_FSEEK(stream, offset, whence) fseek(stream, offset, whence)
- # define OPJ_FTELL(stream) ftell(stream)
- #endif
- #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
- #define JP2_MAGIC "\x0d\x0a\x87\x0a"
- /* position 45: "\xff\x52" */
- #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
- static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *p_file)
- {
- OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
- return l_nb_read ? l_nb_read : (OPJ_SIZE_T) -1;
- }
- static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, FILE *p_user_data)
- {
- if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_SET)) {
- return OPJ_FALSE;
- }
- return OPJ_TRUE;
- }
- static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, FILE *p_user_data)
- {
- if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_CUR)) {
- return -1;
- }
- return p_nb_bytes;
- }
- static OPJ_UINT64 opj_get_data_length_from_file(FILE *p_file)
- {
- OPJ_OFF_T file_length = 0;
- OPJ_FSEEK(p_file, 0, SEEK_END);
- file_length = (OPJ_OFF_T) OPJ_FTELL(p_file);
- OPJ_FSEEK(p_file, 0, SEEK_SET);
- return (OPJ_UINT64) file_length;
- }
- static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *p_file)
- {
- return fwrite(p_buffer, 1, p_nb_bytes, p_file);
- }
- // End of defines and functions copied from openjpeg.c
- /**
- * Create stream from file pointer.
- * A similar funtion was deprecated and removed from openjpeg.c.
- */
- opj_stream_t* util_create_stream(FILE *fp, int is_input)
- {
- opj_stream_t *stream;
- stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, is_input);
- if(!stream)
- {
- return NULL;
- }
- opj_stream_set_read_function(stream, (opj_stream_read_fn) opj_read_from_file);
- opj_stream_set_seek_function(stream, (opj_stream_seek_fn) opj_seek_from_file);
- opj_stream_set_skip_function(stream, (opj_stream_skip_fn) opj_skip_from_file);
- opj_stream_set_user_data(stream, fp, NULL);
- opj_stream_set_user_data_length(stream, opj_get_data_length_from_file(fp));
- opj_stream_set_write_function(stream, (opj_stream_write_fn) opj_write_from_file);
- return stream;
- }
- /**
- * Destroy stream, codec, and image. As long as they aren't null pointers.
- */
- void util_destroy(opj_codec_t *codec, opj_stream_t* stream, opj_image_t *image)
- {
- if(stream != NULL)
- {
- opj_stream_destroy(stream);
- }
- if(codec != NULL)
- {
- opj_destroy_codec(codec);
- }
- if(image != NULL)
- {
- opj_image_destroy(image);
- }
- }
- /**
- * Identify what OPJ_CODEC to use for input file.
- */
- int util_identify(FILE *fp)
- {
- int length;
- unsigned char buffer[12];
- memset(buffer, 0, 12);
- length = fread(buffer, 1, 12, fp);
- if(length != 12)
- {
- return -1;
- }
- fseek(fp, 0, SEEK_SET);
- if(memcmp(buffer, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buffer, JP2_MAGIC, 4) == 0)
- {
- return OPJ_CODEC_JP2;
- }
- else if(memcmp(buffer, J2K_CODESTREAM_MAGIC, 4) == 0)
- {
- return OPJ_CODEC_J2K;
- }
- // TODO: OPJ_CODEC_JPT? OPJ_CODEC_JPP? OPJ_CODEC_JPX? OPJ_CODEC_JPH?
- return -1;
- }
- /**
- * Calculate rowstride for image
- */
- int util_rowstride(opj_image_t *image, int comps_needed)
- {
- return image->comps[0].w * comps_needed;
- // return ((image->comps[0].w * comps_needed * image->comps[0].prec + 7U) / 8U);
- }
- /**
- * Clamp value between 0 and max
- */
- int util_clamp(int value, int max)
- {
- if(value > max)
- {
- value = max;
- }
- else if(value < 0)
- {
- value = 0;
- }
- return value;
- }
- // Debug functions
- #if DEBUG == TRUE
- static void error_callback(const char *msg, void *client_data)
- {
- (void)client_data;
- g_print("[ERROR] %s", msg);
- }
- static void warning_callback(const char *msg, void *client_data)
- {
- (void)client_data;
- g_print("[WARNING] %s", msg);
- }
- static void info_callback(const char *msg, void *client_data)
- {
- (void)client_data;
- g_print("[INFO] %s", msg);
- }
- #endif
- #endif
|