mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-27 13:44:15 +01:00
-plugin videos now need to be in subfolders if you have "coverFolder" for the ini set
-plugins now also play videos which have the magic number as name if no specific video was found -switched from libjpeg to the turbojpeg wrapper from libjpeg-turbo to simplify the whole jpeg decoding code by alot -heavly optimized the video decoding code
This commit is contained in:
parent
fad956006c
commit
bbf0091922
@ -67,7 +67,7 @@ endif
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -lcustomfat -lcustomntfs -lcustomext2fs -lpng -ljpeg -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec -lmad
|
LIBS := -lcustomfat -lcustomntfs -lcustomext2fs -lpng -lturbojpeg -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec -lmad
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/* jconfig.h. Generated automatically by configure. */
|
|
||||||
/* jconfig.cfg --- source file edited by configure script */
|
|
||||||
/* see jconfig.doc for explanations */
|
|
||||||
|
|
||||||
#define HAVE_PROTOTYPES
|
|
||||||
#define HAVE_UNSIGNED_CHAR
|
|
||||||
#define HAVE_UNSIGNED_SHORT
|
|
||||||
#undef void
|
|
||||||
#undef const
|
|
||||||
#undef CHAR_IS_UNSIGNED
|
|
||||||
#define HAVE_STDDEF_H
|
|
||||||
#define HAVE_STDLIB_H
|
|
||||||
#undef NEED_BSD_STRINGS
|
|
||||||
#undef NEED_SYS_TYPES_H
|
|
||||||
#undef NEED_FAR_POINTERS
|
|
||||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
|
||||||
/* Define this if you get warnings about undefined structures. */
|
|
||||||
#undef INCOMPLETE_TYPES_BROKEN
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNALS
|
|
||||||
|
|
||||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
|
||||||
#define INLINE __inline__
|
|
||||||
/* These are for configuring the JPEG memory manager. */
|
|
||||||
#undef DEFAULT_MAX_MEM
|
|
||||||
#undef NO_MKTEMP
|
|
||||||
|
|
||||||
#endif /* JPEG_INTERNALS */
|
|
||||||
|
|
||||||
#ifdef JPEG_CJPEG_DJPEG
|
|
||||||
|
|
||||||
#define BMP_SUPPORTED /* BMP image file format */
|
|
||||||
#define GIF_SUPPORTED /* GIF image file format */
|
|
||||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
|
||||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
|
||||||
#define TARGA_SUPPORTED /* Targa image file format */
|
|
||||||
|
|
||||||
#undef TWO_FILE_COMMANDLINE
|
|
||||||
#undef NEED_SIGNAL_CATCHER
|
|
||||||
#undef DONT_USE_B_MODE
|
|
||||||
|
|
||||||
/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
|
|
||||||
#undef PROGRESS_REPORT
|
|
||||||
|
|
||||||
#endif /* JPEG_CJPEG_DJPEG */
|
|
@ -1,291 +0,0 @@
|
|||||||
/*
|
|
||||||
* jerror.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file defines the error and message codes for the JPEG library.
|
|
||||||
* Edit this file to add new codes, or to translate the message strings to
|
|
||||||
* some other language.
|
|
||||||
* A set of error-reporting macros are defined too. Some applications using
|
|
||||||
* the JPEG library may wish to include this file to get the error codes
|
|
||||||
* and/or the macros.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To define the enum list of message codes, include this file without
|
|
||||||
* defining macro JMESSAGE. To create a message string table, include it
|
|
||||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
|
||||||
*/
|
|
||||||
#ifndef JMESSAGE
|
|
||||||
#ifndef JERROR_H
|
|
||||||
/* First time through, define the enum list */
|
|
||||||
#define JMAKE_ENUM_LIST
|
|
||||||
#else
|
|
||||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
|
||||||
#define JMESSAGE(code,string)
|
|
||||||
#endif /* JERROR_H */
|
|
||||||
#endif /* JMESSAGE */
|
|
||||||
|
|
||||||
#ifdef JMAKE_ENUM_LIST
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
|
|
||||||
#define JMESSAGE(code,string) code ,
|
|
||||||
|
|
||||||
#endif /* JMAKE_ENUM_LIST */
|
|
||||||
|
|
||||||
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
|
|
||||||
|
|
||||||
/* For maintenance convenience, list is alphabetical by message code name */
|
|
||||||
JMESSAGE(JERR_ARITH_NOTIMPL,
|
|
||||||
"Sorry, there are legal restrictions on arithmetic coding")
|
|
||||||
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
|
|
||||||
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
|
|
||||||
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
|
|
||||||
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
|
||||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
|
||||||
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
|
|
||||||
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
|
|
||||||
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
|
|
||||||
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
|
|
||||||
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
|
|
||||||
JMESSAGE(JERR_BAD_LIB_VERSION,
|
|
||||||
"Wrong JPEG library version: library is %d, caller expects %d")
|
|
||||||
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
|
|
||||||
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
|
|
||||||
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
|
|
||||||
JMESSAGE(JERR_BAD_PROGRESSION,
|
|
||||||
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
|
|
||||||
JMESSAGE(JERR_BAD_PROG_SCRIPT,
|
|
||||||
"Invalid progressive parameters at scan script entry %d")
|
|
||||||
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
|
|
||||||
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
|
|
||||||
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
|
|
||||||
JMESSAGE(JERR_BAD_STRUCT_SIZE,
|
|
||||||
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
|
|
||||||
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
|
|
||||||
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
|
|
||||||
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
|
|
||||||
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
|
|
||||||
JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
|
|
||||||
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
|
|
||||||
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
|
|
||||||
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
|
|
||||||
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
|
|
||||||
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
|
|
||||||
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
|
|
||||||
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
|
|
||||||
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
|
|
||||||
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
|
|
||||||
JMESSAGE(JERR_FILE_READ, "Input file read error")
|
|
||||||
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
|
|
||||||
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
|
|
||||||
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
|
|
||||||
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
|
|
||||||
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
|
|
||||||
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
|
|
||||||
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
|
|
||||||
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
|
|
||||||
"Cannot transcode due to multiple use of quantization table %d")
|
|
||||||
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
|
|
||||||
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
|
|
||||||
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
|
|
||||||
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
|
|
||||||
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
|
|
||||||
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
|
|
||||||
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
|
|
||||||
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
|
|
||||||
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
|
|
||||||
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
|
|
||||||
JMESSAGE(JERR_QUANT_COMPONENTS,
|
|
||||||
"Cannot quantize more than %d color components")
|
|
||||||
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
|
|
||||||
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
|
|
||||||
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
|
|
||||||
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
|
|
||||||
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
|
|
||||||
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
|
|
||||||
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
|
|
||||||
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
|
|
||||||
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
|
|
||||||
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
|
|
||||||
JMESSAGE(JERR_TFILE_WRITE,
|
|
||||||
"Write failed on temporary file --- out of disk space?")
|
|
||||||
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
|
|
||||||
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
|
|
||||||
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
|
|
||||||
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
|
|
||||||
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
|
|
||||||
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
|
|
||||||
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
|
|
||||||
JMESSAGE(JMSG_VERSION, JVERSION)
|
|
||||||
JMESSAGE(JTRC_16BIT_TABLES,
|
|
||||||
"Caution: quantization tables are too coarse for baseline JPEG")
|
|
||||||
JMESSAGE(JTRC_ADOBE,
|
|
||||||
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
|
|
||||||
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
|
|
||||||
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
|
|
||||||
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
|
|
||||||
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
|
|
||||||
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
|
|
||||||
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
|
|
||||||
JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
|
|
||||||
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
|
|
||||||
JMESSAGE(JTRC_EOI, "End Of Image")
|
|
||||||
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
|
|
||||||
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
|
|
||||||
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
|
|
||||||
"Warning: thumbnail image size does not match data length %u")
|
|
||||||
JMESSAGE(JTRC_JFIF_EXTENSION,
|
|
||||||
"JFIF extension marker: type 0x%02x, length %u")
|
|
||||||
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
|
|
||||||
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
|
|
||||||
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
|
|
||||||
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
|
|
||||||
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
|
|
||||||
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
|
|
||||||
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
|
|
||||||
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
|
|
||||||
JMESSAGE(JTRC_RST, "RST%d")
|
|
||||||
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
|
|
||||||
"Smoothing not supported with nonstandard sampling ratios")
|
|
||||||
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
|
|
||||||
JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
|
|
||||||
JMESSAGE(JTRC_SOI, "Start of Image")
|
|
||||||
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
|
|
||||||
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
|
|
||||||
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
|
|
||||||
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
|
|
||||||
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
|
|
||||||
JMESSAGE(JTRC_THUMB_JPEG,
|
|
||||||
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_THUMB_PALETTE,
|
|
||||||
"JFIF extension marker: palette thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_THUMB_RGB,
|
|
||||||
"JFIF extension marker: RGB thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_UNKNOWN_IDS,
|
|
||||||
"Unrecognized component IDs %d %d %d, assuming YCbCr")
|
|
||||||
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
|
|
||||||
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
|
|
||||||
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
|
|
||||||
JMESSAGE(JWRN_BOGUS_PROGRESSION,
|
|
||||||
"Inconsistent progression sequence for component %d coefficient %d")
|
|
||||||
JMESSAGE(JWRN_EXTRANEOUS_DATA,
|
|
||||||
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
|
|
||||||
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
|
|
||||||
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
|
|
||||||
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
|
|
||||||
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
|
|
||||||
JMESSAGE(JWRN_MUST_RESYNC,
|
|
||||||
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
|
|
||||||
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
|
|
||||||
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
|
|
||||||
|
|
||||||
#ifdef JMAKE_ENUM_LIST
|
|
||||||
|
|
||||||
JMSG_LASTMSGCODE
|
|
||||||
} J_MESSAGE_CODE;
|
|
||||||
|
|
||||||
#undef JMAKE_ENUM_LIST
|
|
||||||
#endif /* JMAKE_ENUM_LIST */
|
|
||||||
|
|
||||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
|
||||||
#undef JMESSAGE
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef JERROR_H
|
|
||||||
#define JERROR_H
|
|
||||||
|
|
||||||
/* Macros to simplify using the error and trace message stuff */
|
|
||||||
/* The first parameter is either type of cinfo pointer */
|
|
||||||
|
|
||||||
/* Fatal errors (print message and exit) */
|
|
||||||
#define ERREXIT(cinfo,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT1(cinfo,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT2(cinfo,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT3(cinfo,code,p1,p2,p3) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
|
||||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXITS(cinfo,code,str) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
|
|
||||||
#define MAKESTMT(stuff) do { stuff } while (0)
|
|
||||||
|
|
||||||
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
|
|
||||||
#define WARNMS(cinfo,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
#define WARNMS1(cinfo,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
#define WARNMS2(cinfo,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
|
|
||||||
/* Informational/debugging messages */
|
|
||||||
#define TRACEMS(cinfo,lvl,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS1(cinfo,lvl,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
_mp[4] = (p5); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMSS(cinfo,lvl,code,str) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
|
|
||||||
#endif /* JERROR_H */
|
|
@ -1,363 +0,0 @@
|
|||||||
/*
|
|
||||||
* jmorecfg.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains additional configuration options that customize the
|
|
||||||
* JPEG software for special applications or support machine-dependent
|
|
||||||
* optimizations. Most users will not need to touch this file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define BITS_IN_JSAMPLE as either
|
|
||||||
* 8 for 8-bit sample values (the usual setting)
|
|
||||||
* 12 for 12-bit sample values
|
|
||||||
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
|
|
||||||
* JPEG standard, and the IJG code does not support anything else!
|
|
||||||
* We do not support run-time selection of data precision, sorry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum number of components (color channels) allowed in JPEG image.
|
|
||||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
|
||||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
|
||||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
|
||||||
* really short on memory. (Each allowed component costs a hundred or so
|
|
||||||
* bytes of storage, whether actually used in an image or not.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAX_COMPONENTS 10 /* maximum number of image components */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Basic data types.
|
|
||||||
* You may need to change these if you have a machine with unusual data
|
|
||||||
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
|
|
||||||
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
|
|
||||||
* but it had better be at least 16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Representation of a single sample (pixel element value).
|
|
||||||
* We frequently allocate large arrays of these, so it's important to keep
|
|
||||||
* them small. But if you have memory to burn and access to char or short
|
|
||||||
* arrays is very slow on your hardware, you might want to change these.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
|
||||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
|
|
||||||
typedef unsigned char JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
typedef char JSAMPLE;
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
#else
|
|
||||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 255
|
|
||||||
#define CENTERJSAMPLE 128
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
|
||||||
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 12
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
|
|
||||||
* On nearly all machines "short" will do nicely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 4095
|
|
||||||
#define CENTERJSAMPLE 2048
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Representation of a DCT frequency coefficient.
|
|
||||||
* This should be a signed value of at least 16 bits; "short" is usually OK.
|
|
||||||
* Again, we allocate large arrays of these, but you can change to int
|
|
||||||
* if you have memory to burn and "short" is really slow.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JCOEF;
|
|
||||||
|
|
||||||
|
|
||||||
/* Compressed datastreams are represented as arrays of JOCTET.
|
|
||||||
* These must be EXACTLY 8 bits wide, at least once they are written to
|
|
||||||
* external storage. Note that when using the stdio data source/destination
|
|
||||||
* managers, this is also the data type passed to fread/fwrite.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
|
|
||||||
typedef unsigned char JOCTET;
|
|
||||||
#define GETJOCTET(value) (value)
|
|
||||||
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
typedef char JOCTET;
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
#define GETJOCTET(value) (value)
|
|
||||||
#else
|
|
||||||
#define GETJOCTET(value) ((value) & 0xFF)
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
|
|
||||||
/* These typedefs are used for various table entries and so forth.
|
|
||||||
* They must be at least as wide as specified; but making them too big
|
|
||||||
* won't cost a huge amount of memory, so we don't provide special
|
|
||||||
* extraction code like we did for JSAMPLE. (In other words, these
|
|
||||||
* typedefs live at a different point on the speed/space tradeoff curve.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* UINT8 must hold at least the values 0..255. */
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
typedef unsigned char UINT8;
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
typedef char UINT8;
|
|
||||||
#else /* not CHAR_IS_UNSIGNED */
|
|
||||||
typedef short UINT8;
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
/* UINT16 must hold at least the values 0..65535. */
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_SHORT
|
|
||||||
typedef unsigned short UINT16;
|
|
||||||
#else /* not HAVE_UNSIGNED_SHORT */
|
|
||||||
typedef unsigned int UINT16;
|
|
||||||
#endif /* HAVE_UNSIGNED_SHORT */
|
|
||||||
|
|
||||||
/* INT16 must hold at least the values -32768..32767. */
|
|
||||||
|
|
||||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
|
|
||||||
typedef short INT16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* INT32 must hold at least signed 32-bit values. */
|
|
||||||
|
|
||||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
|
||||||
typedef long INT32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
|
||||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
|
||||||
* "unsigned int" is sufficient on all machines. However, if you need to
|
|
||||||
* handle larger images and you don't mind deviating from the spec, you
|
|
||||||
* can change this datatype.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned int JDIMENSION;
|
|
||||||
|
|
||||||
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
|
|
||||||
|
|
||||||
|
|
||||||
/* These macros are used in all function definitions and extern declarations.
|
|
||||||
* You could modify them if you need to change function linkage conventions;
|
|
||||||
* in particular, you'll need to do that to make the library a Windows DLL.
|
|
||||||
* Another application is to make all functions global for use with debuggers
|
|
||||||
* or code profilers that require it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* a function called through method pointers: */
|
|
||||||
#define METHODDEF(type) static type
|
|
||||||
/* a function used only in its module: */
|
|
||||||
#define LOCAL(type) static type
|
|
||||||
/* a function referenced thru EXTERNs: */
|
|
||||||
#define GLOBAL(type) type
|
|
||||||
/* a reference to a GLOBAL function: */
|
|
||||||
#define EXTERN(type) extern type
|
|
||||||
|
|
||||||
|
|
||||||
/* This macro is used to declare a "method", that is, a function pointer.
|
|
||||||
* We want to supply prototype parameters if the compiler can cope.
|
|
||||||
* Note that the arglist parameter must be parenthesized!
|
|
||||||
* Again, you can customize this if you need special linkage keywords.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_PROTOTYPES
|
|
||||||
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
|
|
||||||
#else
|
|
||||||
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Here is the pseudo-keyword for declaring pointers that must be "far"
|
|
||||||
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
|
|
||||||
* by just saying "FAR *" where such a pointer is needed. In a few places
|
|
||||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NEED_FAR_POINTERS
|
|
||||||
#define FAR far
|
|
||||||
#else
|
|
||||||
#define FAR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
|
|
||||||
* in standard header files. Or you may have conflicts with application-
|
|
||||||
* specific header files that you want to include together with these files.
|
|
||||||
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_BOOLEAN
|
|
||||||
typedef int boolean;
|
|
||||||
#endif
|
|
||||||
#ifndef FALSE /* in case these macros already exist */
|
|
||||||
#define FALSE 0 /* values of boolean */
|
|
||||||
#endif
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The remaining options affect code selection within the JPEG library,
|
|
||||||
* but they don't need to be visible to most applications using the library.
|
|
||||||
* To minimize application namespace pollution, the symbols won't be
|
|
||||||
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNALS
|
|
||||||
#define JPEG_INTERNAL_OPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNAL_OPTIONS
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These defines indicate whether to include various optional functions.
|
|
||||||
* Undefining some of these symbols will produce a smaller but less capable
|
|
||||||
* library. Note that you can leave certain source files out of the
|
|
||||||
* compilation/linking process if you've #undef'd the corresponding symbols.
|
|
||||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
|
|
||||||
|
|
||||||
/* Capability options common to encoder and decoder: */
|
|
||||||
|
|
||||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
|
||||||
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
|
|
||||||
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
|
|
||||||
|
|
||||||
/* Encoder capability options: */
|
|
||||||
|
|
||||||
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
|
||||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
|
||||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
|
||||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
|
||||||
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
|
|
||||||
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
|
|
||||||
* precision, so jchuff.c normally uses entropy optimization to compute
|
|
||||||
* usable tables for higher precision. If you don't want to do optimization,
|
|
||||||
* you'll have to supply different default Huffman tables.
|
|
||||||
* The exact same statements apply for progressive JPEG: the default tables
|
|
||||||
* don't work for progressive mode. (This may get fixed, however.)
|
|
||||||
*/
|
|
||||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
|
||||||
|
|
||||||
/* Decoder capability options: */
|
|
||||||
|
|
||||||
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
|
||||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
|
||||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
|
||||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
|
||||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
|
||||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
|
||||||
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
|
|
||||||
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
|
|
||||||
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
|
|
||||||
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
|
|
||||||
|
|
||||||
/* more capability options later, no doubt */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ordering of RGB data in scanlines passed to or from the application.
|
|
||||||
* If your application wants to deal with data in the order B,G,R, just
|
|
||||||
* change these macros. You can also deal with formats such as R,G,B,X
|
|
||||||
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
|
|
||||||
* the offsets will also change the order in which colormap data is organized.
|
|
||||||
* RESTRICTIONS:
|
|
||||||
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
|
|
||||||
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
|
|
||||||
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
|
|
||||||
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
|
|
||||||
* is not 3 (they don't understand about dummy color components!). So you
|
|
||||||
* can't use color quantization if you change that value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
|
|
||||||
#define RGB_GREEN 1 /* Offset of Green */
|
|
||||||
#define RGB_BLUE 2 /* Offset of Blue */
|
|
||||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
|
||||||
|
|
||||||
|
|
||||||
/* Definitions for speed-related optimizations. */
|
|
||||||
|
|
||||||
|
|
||||||
/* If your compiler supports inline functions, define INLINE
|
|
||||||
* as the inline keyword; otherwise define it as empty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INLINE
|
|
||||||
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
|
|
||||||
#define INLINE __inline__
|
|
||||||
#endif
|
|
||||||
#ifndef INLINE
|
|
||||||
#define INLINE /* default is to define it as empty */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
|
|
||||||
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
|
|
||||||
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MULTIPLIER
|
|
||||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* FAST_FLOAT should be either float or double, whichever is done faster
|
|
||||||
* by your compiler. (Note that this type is only used in the floating point
|
|
||||||
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
|
|
||||||
* Typically, float is faster in ANSI C compilers, while double is faster in
|
|
||||||
* pre-ANSI compilers (because they insist on converting to double anyway).
|
|
||||||
* The code below therefore chooses float if we have ANSI-style prototypes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FAST_FLOAT
|
|
||||||
#ifdef HAVE_PROTOTYPES
|
|
||||||
#define FAST_FLOAT float
|
|
||||||
#else
|
|
||||||
#define FAST_FLOAT double
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* JPEG_INTERNAL_OPTIONS */
|
|
File diff suppressed because it is too large
Load Diff
932
portlibs/include/turbojpeg.h
Normal file
932
portlibs/include/turbojpeg.h
Normal file
@ -0,0 +1,932 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C)2009-2013 D. R. Commander. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TURBOJPEG_H__
|
||||||
|
#define __TURBOJPEG_H__
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(DLLDEFINE)
|
||||||
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define DLLEXPORT
|
||||||
|
#endif
|
||||||
|
#define DLLCALL
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup TurboJPEG
|
||||||
|
* TurboJPEG API. This API provides an interface for generating, decoding, and
|
||||||
|
* transforming planar YUV and JPEG images in memory.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of chrominance subsampling options
|
||||||
|
*/
|
||||||
|
#define TJ_NUMSAMP 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chrominance subsampling options.
|
||||||
|
* When an image is converted from the RGB to the YCbCr colorspace as part of
|
||||||
|
* the JPEG compression process, some of the Cb and Cr (chrominance) components
|
||||||
|
* can be discarded or averaged together to produce a smaller image with little
|
||||||
|
* perceptible loss of image clarity (the human eye is more sensitive to small
|
||||||
|
* changes in brightness than small changes in color.) This is called
|
||||||
|
* "chrominance subsampling".
|
||||||
|
* <p>
|
||||||
|
* NOTE: Technically, the JPEG format uses the YCbCr colorspace, but per the
|
||||||
|
* convention of the digital video community, the TurboJPEG API uses "YUV" to
|
||||||
|
* refer to an image format consisting of Y, Cb, and Cr image planes.
|
||||||
|
*/
|
||||||
|
enum TJSAMP
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG or
|
||||||
|
* YUV image will contain one chrominance component for every pixel in the
|
||||||
|
* source image.
|
||||||
|
*/
|
||||||
|
TJSAMP_444=0,
|
||||||
|
/**
|
||||||
|
* 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one
|
||||||
|
* chrominance component for every 2x1 block of pixels in the source image.
|
||||||
|
*/
|
||||||
|
TJSAMP_422,
|
||||||
|
/**
|
||||||
|
* 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one
|
||||||
|
* chrominance component for every 2x2 block of pixels in the source image.
|
||||||
|
*/
|
||||||
|
TJSAMP_420,
|
||||||
|
/**
|
||||||
|
* Grayscale. The JPEG or YUV image will contain no chrominance components.
|
||||||
|
*/
|
||||||
|
TJSAMP_GRAY,
|
||||||
|
/**
|
||||||
|
* 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one
|
||||||
|
* chrominance component for every 1x2 block of pixels in the source image.
|
||||||
|
* Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
|
||||||
|
*/
|
||||||
|
TJSAMP_440
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCU block width (in pixels) for a given level of chrominance subsampling.
|
||||||
|
* MCU block sizes:
|
||||||
|
* - 8x8 for no subsampling or grayscale
|
||||||
|
* - 16x8 for 4:2:2
|
||||||
|
* - 8x16 for 4:4:0
|
||||||
|
* - 16x16 for 4:2:0
|
||||||
|
*/
|
||||||
|
static const int tjMCUWidth[TJ_NUMSAMP] = {8, 16, 16, 8, 8};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCU block height (in pixels) for a given level of chrominance subsampling.
|
||||||
|
* MCU block sizes:
|
||||||
|
* - 8x8 for no subsampling or grayscale
|
||||||
|
* - 16x8 for 4:2:2
|
||||||
|
* - 8x16 for 4:4:0
|
||||||
|
* - 16x16 for 4:2:0
|
||||||
|
*/
|
||||||
|
static const int tjMCUHeight[TJ_NUMSAMP] = {8, 8, 16, 8, 16};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of pixel formats
|
||||||
|
*/
|
||||||
|
#define TJ_NUMPF 11
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pixel formats
|
||||||
|
*/
|
||||||
|
enum TJPF
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* RGB pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 3-byte pixels in the order R, G, B from lowest to highest byte
|
||||||
|
* address within each pixel.
|
||||||
|
*/
|
||||||
|
TJPF_RGB=0,
|
||||||
|
/**
|
||||||
|
* BGR pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 3-byte pixels in the order B, G, R from lowest to highest byte
|
||||||
|
* address within each pixel.
|
||||||
|
*/
|
||||||
|
TJPF_BGR,
|
||||||
|
/**
|
||||||
|
* RGBX pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 4-byte pixels in the order R, G, B from lowest to highest byte
|
||||||
|
* address within each pixel. The X component is ignored when compressing
|
||||||
|
* and undefined when decompressing.
|
||||||
|
*/
|
||||||
|
TJPF_RGBX,
|
||||||
|
/**
|
||||||
|
* BGRX pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 4-byte pixels in the order B, G, R from lowest to highest byte
|
||||||
|
* address within each pixel. The X component is ignored when compressing
|
||||||
|
* and undefined when decompressing.
|
||||||
|
*/
|
||||||
|
TJPF_BGRX,
|
||||||
|
/**
|
||||||
|
* XBGR pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 4-byte pixels in the order R, G, B from highest to lowest byte
|
||||||
|
* address within each pixel. The X component is ignored when compressing
|
||||||
|
* and undefined when decompressing.
|
||||||
|
*/
|
||||||
|
TJPF_XBGR,
|
||||||
|
/**
|
||||||
|
* XRGB pixel format. The red, green, and blue components in the image are
|
||||||
|
* stored in 4-byte pixels in the order B, G, R from highest to lowest byte
|
||||||
|
* address within each pixel. The X component is ignored when compressing
|
||||||
|
* and undefined when decompressing.
|
||||||
|
*/
|
||||||
|
TJPF_XRGB,
|
||||||
|
/**
|
||||||
|
* Grayscale pixel format. Each 1-byte pixel represents a luminance
|
||||||
|
* (brightness) level from 0 to 255.
|
||||||
|
*/
|
||||||
|
TJPF_GRAY,
|
||||||
|
/**
|
||||||
|
* RGBA pixel format. This is the same as @ref TJPF_RGBX, except that when
|
||||||
|
* decompressing, the X component is guaranteed to be 0xFF, which can be
|
||||||
|
* interpreted as an opaque alpha channel.
|
||||||
|
*/
|
||||||
|
TJPF_RGBA,
|
||||||
|
/**
|
||||||
|
* BGRA pixel format. This is the same as @ref TJPF_BGRX, except that when
|
||||||
|
* decompressing, the X component is guaranteed to be 0xFF, which can be
|
||||||
|
* interpreted as an opaque alpha channel.
|
||||||
|
*/
|
||||||
|
TJPF_BGRA,
|
||||||
|
/**
|
||||||
|
* ABGR pixel format. This is the same as @ref TJPF_XBGR, except that when
|
||||||
|
* decompressing, the X component is guaranteed to be 0xFF, which can be
|
||||||
|
* interpreted as an opaque alpha channel.
|
||||||
|
*/
|
||||||
|
TJPF_ABGR,
|
||||||
|
/**
|
||||||
|
* ARGB pixel format. This is the same as @ref TJPF_XRGB, except that when
|
||||||
|
* decompressing, the X component is guaranteed to be 0xFF, which can be
|
||||||
|
* interpreted as an opaque alpha channel.
|
||||||
|
*/
|
||||||
|
TJPF_ARGB
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Red offset (in bytes) for a given pixel format. This specifies the number
|
||||||
|
* of bytes that the red component is offset from the start of the pixel. For
|
||||||
|
* instance, if a pixel of format TJ_BGRX is stored in <tt>char pixel[]</tt>,
|
||||||
|
* then the red component will be <tt>pixel[tjRedOffset[TJ_BGRX]]</tt>.
|
||||||
|
*/
|
||||||
|
static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1};
|
||||||
|
/**
|
||||||
|
* Green offset (in bytes) for a given pixel format. This specifies the number
|
||||||
|
* of bytes that the green component is offset from the start of the pixel.
|
||||||
|
* For instance, if a pixel of format TJ_BGRX is stored in
|
||||||
|
* <tt>char pixel[]</tt>, then the green component will be
|
||||||
|
* <tt>pixel[tjGreenOffset[TJ_BGRX]]</tt>.
|
||||||
|
*/
|
||||||
|
static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2};
|
||||||
|
/**
|
||||||
|
* Blue offset (in bytes) for a given pixel format. This specifies the number
|
||||||
|
* of bytes that the Blue component is offset from the start of the pixel. For
|
||||||
|
* instance, if a pixel of format TJ_BGRX is stored in <tt>char pixel[]</tt>,
|
||||||
|
* then the blue component will be <tt>pixel[tjBlueOffset[TJ_BGRX]]</tt>.
|
||||||
|
*/
|
||||||
|
static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pixel size (in bytes) for a given pixel format.
|
||||||
|
*/
|
||||||
|
static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The uncompressed source/destination image is stored in bottom-up (Windows,
|
||||||
|
* OpenGL) order, not top-down (X11) order.
|
||||||
|
*/
|
||||||
|
#define TJFLAG_BOTTOMUP 2
|
||||||
|
/**
|
||||||
|
* Turn off CPU auto-detection and force TurboJPEG to use MMX code (if the
|
||||||
|
* underlying codec supports it.)
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FORCEMMX 8
|
||||||
|
/**
|
||||||
|
* Turn off CPU auto-detection and force TurboJPEG to use SSE code (if the
|
||||||
|
* underlying codec supports it.)
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FORCESSE 16
|
||||||
|
/**
|
||||||
|
* Turn off CPU auto-detection and force TurboJPEG to use SSE2 code (if the
|
||||||
|
* underlying codec supports it.)
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FORCESSE2 32
|
||||||
|
/**
|
||||||
|
* Turn off CPU auto-detection and force TurboJPEG to use SSE3 code (if the
|
||||||
|
* underlying codec supports it.)
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FORCESSE3 128
|
||||||
|
/**
|
||||||
|
* When decompressing an image that was compressed using chrominance
|
||||||
|
* subsampling, use the fastest chrominance upsampling algorithm available in
|
||||||
|
* the underlying codec. The default is to use smooth upsampling, which
|
||||||
|
* creates a smooth transition between neighboring chrominance components in
|
||||||
|
* order to reduce upsampling artifacts in the decompressed image.
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FASTUPSAMPLE 256
|
||||||
|
/**
|
||||||
|
* Disable buffer (re)allocation. If passed to #tjCompress2() or
|
||||||
|
* #tjTransform(), this flag will cause those functions to generate an error if
|
||||||
|
* the JPEG image buffer is invalid or too small rather than attempting to
|
||||||
|
* allocate or reallocate that buffer. This reproduces the behavior of earlier
|
||||||
|
* versions of TurboJPEG.
|
||||||
|
*/
|
||||||
|
#define TJFLAG_NOREALLOC 1024
|
||||||
|
/**
|
||||||
|
* Use the fastest DCT/IDCT algorithm available in the underlying codec. The
|
||||||
|
* default if this flag is not specified is implementation-specific. For
|
||||||
|
* example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast
|
||||||
|
* algorithm by default when compressing, because this has been shown to have
|
||||||
|
* only a very slight effect on accuracy, but it uses the accurate algorithm
|
||||||
|
* when decompressing, because this has been shown to have a larger effect.
|
||||||
|
*/
|
||||||
|
#define TJFLAG_FASTDCT 2048
|
||||||
|
/**
|
||||||
|
* Use the most accurate DCT/IDCT algorithm available in the underlying codec.
|
||||||
|
* The default if this flag is not specified is implementation-specific. For
|
||||||
|
* example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast
|
||||||
|
* algorithm by default when compressing, because this has been shown to have
|
||||||
|
* only a very slight effect on accuracy, but it uses the accurate algorithm
|
||||||
|
* when decompressing, because this has been shown to have a larger effect.
|
||||||
|
*/
|
||||||
|
#define TJFLAG_ACCURATEDCT 4096
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of transform operations
|
||||||
|
*/
|
||||||
|
#define TJ_NUMXOP 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform operations for #tjTransform()
|
||||||
|
*/
|
||||||
|
enum TJXOP
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Do not transform the position of the image pixels
|
||||||
|
*/
|
||||||
|
TJXOP_NONE=0,
|
||||||
|
/**
|
||||||
|
* Flip (mirror) image horizontally. This transform is imperfect if there
|
||||||
|
* are any partial MCU blocks on the right edge (see #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_HFLIP,
|
||||||
|
/**
|
||||||
|
* Flip (mirror) image vertically. This transform is imperfect if there are
|
||||||
|
* any partial MCU blocks on the bottom edge (see #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_VFLIP,
|
||||||
|
/**
|
||||||
|
* Transpose image (flip/mirror along upper left to lower right axis.) This
|
||||||
|
* transform is always perfect.
|
||||||
|
*/
|
||||||
|
TJXOP_TRANSPOSE,
|
||||||
|
/**
|
||||||
|
* Transverse transpose image (flip/mirror along upper right to lower left
|
||||||
|
* axis.) This transform is imperfect if there are any partial MCU blocks in
|
||||||
|
* the image (see #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_TRANSVERSE,
|
||||||
|
/**
|
||||||
|
* Rotate image clockwise by 90 degrees. This transform is imperfect if
|
||||||
|
* there are any partial MCU blocks on the bottom edge (see
|
||||||
|
* #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_ROT90,
|
||||||
|
/**
|
||||||
|
* Rotate image 180 degrees. This transform is imperfect if there are any
|
||||||
|
* partial MCU blocks in the image (see #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_ROT180,
|
||||||
|
/**
|
||||||
|
* Rotate image counter-clockwise by 90 degrees. This transform is imperfect
|
||||||
|
* if there are any partial MCU blocks on the right edge (see
|
||||||
|
* #TJXOPT_PERFECT.)
|
||||||
|
*/
|
||||||
|
TJXOP_ROT270
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This option will cause #tjTransform() to return an error if the transform is
|
||||||
|
* not perfect. Lossless transforms operate on MCU blocks, whose size depends
|
||||||
|
* on the level of chrominance subsampling used (see #tjMCUWidth
|
||||||
|
* and #tjMCUHeight.) If the image's width or height is not evenly divisible
|
||||||
|
* by the MCU block size, then there will be partial MCU blocks on the right
|
||||||
|
* and/or bottom edges. It is not possible to move these partial MCU blocks to
|
||||||
|
* the top or left of the image, so any transform that would require that is
|
||||||
|
* "imperfect." If this option is not specified, then any partial MCU blocks
|
||||||
|
* that cannot be transformed will be left in place, which will create
|
||||||
|
* odd-looking strips on the right or bottom edge of the image.
|
||||||
|
*/
|
||||||
|
#define TJXOPT_PERFECT 1
|
||||||
|
/**
|
||||||
|
* This option will cause #tjTransform() to discard any partial MCU blocks that
|
||||||
|
* cannot be transformed.
|
||||||
|
*/
|
||||||
|
#define TJXOPT_TRIM 2
|
||||||
|
/**
|
||||||
|
* This option will enable lossless cropping. See #tjTransform() for more
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
#define TJXOPT_CROP 4
|
||||||
|
/**
|
||||||
|
* This option will discard the color data in the input image and produce
|
||||||
|
* a grayscale output image.
|
||||||
|
*/
|
||||||
|
#define TJXOPT_GRAY 8
|
||||||
|
/**
|
||||||
|
* This option will prevent #tjTransform() from outputting a JPEG image for
|
||||||
|
* this particular transform (this can be used in conjunction with a custom
|
||||||
|
* filter to capture the transformed DCT coefficients without transcoding
|
||||||
|
* them.)
|
||||||
|
*/
|
||||||
|
#define TJXOPT_NOOUTPUT 16
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scaling factor
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Numerator
|
||||||
|
*/
|
||||||
|
int num;
|
||||||
|
/**
|
||||||
|
* Denominator
|
||||||
|
*/
|
||||||
|
int denom;
|
||||||
|
} tjscalingfactor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cropping region
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The left boundary of the cropping region. This must be evenly divisible
|
||||||
|
* by the MCU block width (see #tjMCUWidth.)
|
||||||
|
*/
|
||||||
|
int x;
|
||||||
|
/**
|
||||||
|
* The upper boundary of the cropping region. This must be evenly divisible
|
||||||
|
* by the MCU block height (see #tjMCUHeight.)
|
||||||
|
*/
|
||||||
|
int y;
|
||||||
|
/**
|
||||||
|
* The width of the cropping region. Setting this to 0 is the equivalent of
|
||||||
|
* setting it to the width of the source JPEG image - x.
|
||||||
|
*/
|
||||||
|
int w;
|
||||||
|
/**
|
||||||
|
* The height of the cropping region. Setting this to 0 is the equivalent of
|
||||||
|
* setting it to the height of the source JPEG image - y.
|
||||||
|
*/
|
||||||
|
int h;
|
||||||
|
} tjregion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lossless transform
|
||||||
|
*/
|
||||||
|
typedef struct tjtransform
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cropping region
|
||||||
|
*/
|
||||||
|
tjregion r;
|
||||||
|
/**
|
||||||
|
* One of the @ref TJXOP "transform operations"
|
||||||
|
*/
|
||||||
|
int op;
|
||||||
|
/**
|
||||||
|
* The bitwise OR of one of more of the @ref TJXOPT_CROP "transform options"
|
||||||
|
*/
|
||||||
|
int options;
|
||||||
|
/**
|
||||||
|
* Arbitrary data that can be accessed within the body of the callback
|
||||||
|
* function
|
||||||
|
*/
|
||||||
|
void *data;
|
||||||
|
/**
|
||||||
|
* A callback function that can be used to modify the DCT coefficients
|
||||||
|
* after they are losslessly transformed but before they are transcoded to a
|
||||||
|
* new JPEG image. This allows for custom filters or other transformations
|
||||||
|
* to be applied in the frequency domain.
|
||||||
|
*
|
||||||
|
* @param coeffs pointer to an array of transformed DCT coefficients. (NOTE:
|
||||||
|
* this pointer is not guaranteed to be valid once the callback
|
||||||
|
* returns, so applications wishing to hand off the DCT coefficients
|
||||||
|
* to another function or library should make a copy of them within
|
||||||
|
* the body of the callback.)
|
||||||
|
* @param arrayRegion #tjregion structure containing the width and height of
|
||||||
|
* the array pointed to by <tt>coeffs</tt> as well as its offset
|
||||||
|
* relative to the component plane. TurboJPEG implementations may
|
||||||
|
* choose to split each component plane into multiple DCT coefficient
|
||||||
|
* arrays and call the callback function once for each array.
|
||||||
|
* @param planeRegion #tjregion structure containing the width and height of
|
||||||
|
* the component plane to which <tt>coeffs</tt> belongs
|
||||||
|
* @param componentID ID number of the component plane to which
|
||||||
|
* <tt>coeffs</tt> belongs (Y, Cb, and Cr have, respectively, ID's of
|
||||||
|
* 0, 1, and 2 in typical JPEG images.)
|
||||||
|
* @param transformID ID number of the transformed image to which
|
||||||
|
* <tt>coeffs</tt> belongs. This is the same as the index of the
|
||||||
|
* transform in the <tt>transforms</tt> array that was passed to
|
||||||
|
* #tjTransform().
|
||||||
|
* @param transform a pointer to a #tjtransform structure that specifies the
|
||||||
|
* parameters and/or cropping region for this transform
|
||||||
|
*
|
||||||
|
* @return 0 if the callback was successful, or -1 if an error occurred.
|
||||||
|
*/
|
||||||
|
int (*customFilter)(short *coeffs, tjregion arrayRegion,
|
||||||
|
tjregion planeRegion, int componentIndex, int transformIndex,
|
||||||
|
struct tjtransform *transform);
|
||||||
|
} tjtransform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TurboJPEG instance handle
|
||||||
|
*/
|
||||||
|
typedef void* tjhandle;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pad the given width to the nearest 32-bit boundary
|
||||||
|
*/
|
||||||
|
#define TJPAD(width) (((width)+3)&(~3))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the scaled value of <tt>dimension</tt> using the given scaling
|
||||||
|
* factor. This macro performs the integer equivalent of <tt>ceil(dimension *
|
||||||
|
* scalingFactor)</tt>.
|
||||||
|
*/
|
||||||
|
#define TJSCALED(dimension, scalingFactor) ((dimension * scalingFactor.num \
|
||||||
|
+ scalingFactor.denom - 1) / scalingFactor.denom)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TurboJPEG compressor instance.
|
||||||
|
*
|
||||||
|
* @return a handle to the newly-created instance, or NULL if an error
|
||||||
|
* occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compress an RGB or grayscale image into a JPEG image.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG compressor or transformer instance
|
||||||
|
* @param srcBuf pointer to an image buffer containing RGB or grayscale pixels
|
||||||
|
* to be compressed
|
||||||
|
* @param width width (in pixels) of the source image
|
||||||
|
* @param pitch bytes per line of the source image. Normally, this should be
|
||||||
|
* <tt>width * #tjPixelSize[pixelFormat]</tt> if the image is unpadded,
|
||||||
|
* or <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line of
|
||||||
|
* the image is padded to the nearest 32-bit boundary, as is the case
|
||||||
|
* for Windows bitmaps. You can also be clever and use this parameter
|
||||||
|
* to skip lines, etc. Setting this parameter to 0 is the equivalent of
|
||||||
|
* setting it to <tt>width * #tjPixelSize[pixelFormat]</tt>.
|
||||||
|
* @param height height (in pixels) of the source image
|
||||||
|
* @param pixelFormat pixel format of the source image (see @ref TJPF
|
||||||
|
* "Pixel formats".)
|
||||||
|
* @param jpegBuf address of a pointer to an image buffer that will receive the
|
||||||
|
* JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer
|
||||||
|
* to accommodate the size of the JPEG image. Thus, you can choose to:
|
||||||
|
* -# pre-allocate the JPEG buffer with an arbitrary size using
|
||||||
|
* #tjAlloc() and let TurboJPEG grow the buffer as needed,
|
||||||
|
* -# set <tt>*jpegBuf</tt> to NULL to tell TurboJPEG to allocate the
|
||||||
|
* buffer for you, or
|
||||||
|
* -# pre-allocate the buffer to a "worst case" size determined by
|
||||||
|
* calling #tjBufSize(). This should ensure that the buffer never has
|
||||||
|
* to be re-allocated (setting #TJFLAG_NOREALLOC guarantees this.)
|
||||||
|
* .
|
||||||
|
* If you choose option 1, <tt>*jpegSize</tt> should be set to the
|
||||||
|
* size of your pre-allocated buffer. In any case, unless you have
|
||||||
|
* set #TJFLAG_NOREALLOC, you should always check <tt>*jpegBuf</tt> upon
|
||||||
|
* return from this function, as it may have changed.
|
||||||
|
* @param jpegSize pointer to an unsigned long variable that holds the size of
|
||||||
|
* the JPEG image buffer. If <tt>*jpegBuf</tt> points to a
|
||||||
|
* pre-allocated buffer, then <tt>*jpegSize</tt> should be set to the
|
||||||
|
* size of the buffer. Upon return, <tt>*jpegSize</tt> will contain the
|
||||||
|
* size of the JPEG image (in bytes.)
|
||||||
|
* @param jpegSubsamp the level of chrominance subsampling to be used when
|
||||||
|
* generating the JPEG image (see @ref TJSAMP
|
||||||
|
* "Chrominance subsampling options".)
|
||||||
|
* @param jpegQual the image quality of the generated JPEG image (1 = worst,
|
||||||
|
100 = best)
|
||||||
|
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
|
||||||
|
* "flags".
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
|
||||||
|
int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf,
|
||||||
|
unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum size of the buffer (in bytes) required to hold a JPEG image with
|
||||||
|
* the given parameters. The number of bytes returned by this function is
|
||||||
|
* larger than the size of the uncompressed source image. The reason for this
|
||||||
|
* is that the JPEG format uses 16-bit coefficients, and it is thus possible
|
||||||
|
* for a very high-quality JPEG image with very high-frequency content to
|
||||||
|
* expand rather than compress when converted to the JPEG format. Such images
|
||||||
|
* represent a very rare corner case, but since there is no way to predict the
|
||||||
|
* size of a JPEG image prior to compression, the corner case has to be
|
||||||
|
* handled.
|
||||||
|
*
|
||||||
|
* @param width width of the image (in pixels)
|
||||||
|
* @param height height of the image (in pixels)
|
||||||
|
* @param jpegSubsamp the level of chrominance subsampling to be used when
|
||||||
|
* generating the JPEG image (see @ref TJSAMP
|
||||||
|
* "Chrominance subsampling options".)
|
||||||
|
*
|
||||||
|
* @return the maximum size of the buffer (in bytes) required to hold the
|
||||||
|
* image, or -1 if the arguments are out of bounds.
|
||||||
|
*/
|
||||||
|
DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
|
||||||
|
int jpegSubsamp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the buffer (in bytes) required to hold a YUV planar image with
|
||||||
|
* the given parameters.
|
||||||
|
*
|
||||||
|
* @param width width of the image (in pixels)
|
||||||
|
* @param height height of the image (in pixels)
|
||||||
|
* @param subsamp level of chrominance subsampling in the image (see
|
||||||
|
* @ref TJSAMP "Chrominance subsampling options".)
|
||||||
|
*
|
||||||
|
* @return the size of the buffer (in bytes) required to hold the image, or
|
||||||
|
* -1 if the arguments are out of bounds.
|
||||||
|
*/
|
||||||
|
DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
|
||||||
|
int subsamp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode an RGB or grayscale image into a YUV planar image. This function
|
||||||
|
* uses the accelerated color conversion routines in TurboJPEG's underlying
|
||||||
|
* codec to produce a planar YUV image that is suitable for X Video.
|
||||||
|
* Specifically, if the chrominance components are subsampled along the
|
||||||
|
* horizontal dimension, then the width of the luminance plane is padded to the
|
||||||
|
* nearest multiple of 2 in the output image (same goes for the height of the
|
||||||
|
* luminance plane, if the chrominance components are subsampled along the
|
||||||
|
* vertical dimension.) Also, each line of each plane in the output image is
|
||||||
|
* padded to 4 bytes. Although this will work with any subsampling option, it
|
||||||
|
* is really only useful in combination with TJ_420, which produces an image
|
||||||
|
* compatible with the I420 (AKA "YUV420P") format.
|
||||||
|
* <p>
|
||||||
|
* NOTE: Technically, the JPEG format uses the YCbCr colorspace, but per the
|
||||||
|
* convention of the digital video community, the TurboJPEG API uses "YUV" to
|
||||||
|
* refer to an image format consisting of Y, Cb, and Cr image planes.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG compressor or transformer instance
|
||||||
|
* @param srcBuf pointer to an image buffer containing RGB or grayscale pixels
|
||||||
|
* to be encoded
|
||||||
|
* @param width width (in pixels) of the source image
|
||||||
|
* @param pitch bytes per line of the source image. Normally, this should be
|
||||||
|
* <tt>width * #tjPixelSize[pixelFormat]</tt> if the image is unpadded,
|
||||||
|
* or <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line of
|
||||||
|
* the image is padded to the nearest 32-bit boundary, as is the case
|
||||||
|
* for Windows bitmaps. You can also be clever and use this parameter
|
||||||
|
* to skip lines, etc. Setting this parameter to 0 is the equivalent of
|
||||||
|
* setting it to <tt>width * #tjPixelSize[pixelFormat]</tt>.
|
||||||
|
* @param height height (in pixels) of the source image
|
||||||
|
* @param pixelFormat pixel format of the source image (see @ref TJPF
|
||||||
|
* "Pixel formats".)
|
||||||
|
* @param dstBuf pointer to an image buffer that will receive the YUV image.
|
||||||
|
* Use #tjBufSizeYUV() to determine the appropriate size for this buffer
|
||||||
|
* based on the image width, height, and level of chrominance
|
||||||
|
* subsampling.
|
||||||
|
* @param subsamp the level of chrominance subsampling to be used when
|
||||||
|
* generating the YUV image (see @ref TJSAMP
|
||||||
|
* "Chrominance subsampling options".)
|
||||||
|
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
|
||||||
|
* "flags".
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle,
|
||||||
|
unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat,
|
||||||
|
unsigned char *dstBuf, int subsamp, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TurboJPEG decompressor instance.
|
||||||
|
*
|
||||||
|
* @return a handle to the newly-created instance, or NULL if an error
|
||||||
|
* occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a JPEG image without decompressing it.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG decompressor or transformer instance
|
||||||
|
* @param jpegBuf pointer to a buffer containing a JPEG image
|
||||||
|
* @param jpegSize size of the JPEG image (in bytes)
|
||||||
|
* @param width pointer to an integer variable that will receive the width (in
|
||||||
|
* pixels) of the JPEG image
|
||||||
|
* @param height pointer to an integer variable that will receive the height
|
||||||
|
* (in pixels) of the JPEG image
|
||||||
|
* @param jpegSubsamp pointer to an integer variable that will receive the
|
||||||
|
* level of chrominance subsampling used when compressing the JPEG image
|
||||||
|
* (see @ref TJSAMP "Chrominance subsampling options".)
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
|
||||||
|
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
|
||||||
|
int *jpegSubsamp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of fractional scaling factors that the JPEG decompressor in
|
||||||
|
* this implementation of TurboJPEG supports.
|
||||||
|
*
|
||||||
|
* @param numscalingfactors pointer to an integer variable that will receive
|
||||||
|
* the number of elements in the list
|
||||||
|
*
|
||||||
|
* @return a pointer to a list of fractional scaling factors, or NULL if an
|
||||||
|
* error is encountered (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompress a JPEG image to an RGB or grayscale image.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG decompressor or transformer instance
|
||||||
|
* @param jpegBuf pointer to a buffer containing the JPEG image to decompress
|
||||||
|
* @param jpegSize size of the JPEG image (in bytes)
|
||||||
|
* @param dstBuf pointer to an image buffer that will receive the decompressed
|
||||||
|
* image. This buffer should normally be <tt>pitch * scaledHeight</tt>
|
||||||
|
* bytes in size, where <tt>scaledHeight</tt> can be determined by
|
||||||
|
* calling #TJSCALED() with the JPEG image height and one of the scaling
|
||||||
|
* factors returned by #tjGetScalingFactors(). The <tt>dstBuf</tt>
|
||||||
|
* pointer may also be used to decompress into a specific region of a
|
||||||
|
* larger buffer.
|
||||||
|
* @param width desired width (in pixels) of the destination image. If this is
|
||||||
|
* different than the width of the JPEG image being decompressed, then
|
||||||
|
* TurboJPEG will use scaling in the JPEG decompressor to generate the
|
||||||
|
* largest possible image that will fit within the desired width. If
|
||||||
|
* <tt>width</tt> is set to 0, then only the height will be considered
|
||||||
|
* when determining the scaled image size.
|
||||||
|
* @param pitch bytes per line of the destination image. Normally, this is
|
||||||
|
* <tt>scaledWidth * #tjPixelSize[pixelFormat]</tt> if the decompressed
|
||||||
|
* image is unpadded, else <tt>#TJPAD(scaledWidth *
|
||||||
|
* #tjPixelSize[pixelFormat])</tt> if each line of the decompressed
|
||||||
|
* image is padded to the nearest 32-bit boundary, as is the case for
|
||||||
|
* Windows bitmaps. (NOTE: <tt>scaledWidth</tt> can be determined by
|
||||||
|
* calling #TJSCALED() with the JPEG image width and one of the scaling
|
||||||
|
* factors returned by #tjGetScalingFactors().) You can also be clever
|
||||||
|
* and use the pitch parameter to skip lines, etc. Setting this
|
||||||
|
* parameter to 0 is the equivalent of setting it to <tt>scaledWidth
|
||||||
|
* * #tjPixelSize[pixelFormat]</tt>.
|
||||||
|
* @param height desired height (in pixels) of the destination image. If this
|
||||||
|
* is different than the height of the JPEG image being decompressed,
|
||||||
|
* then TurboJPEG will use scaling in the JPEG decompressor to generate
|
||||||
|
* the largest possible image that will fit within the desired height.
|
||||||
|
* If <tt>height</tt> is set to 0, then only the width will be
|
||||||
|
* considered when determining the scaled image size.
|
||||||
|
* @param pixelFormat pixel format of the destination image (see @ref
|
||||||
|
* TJPF "Pixel formats".)
|
||||||
|
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
|
||||||
|
* "flags".
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle,
|
||||||
|
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
|
||||||
|
int width, int pitch, int height, int pixelFormat, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompress a JPEG image to a YUV planar image. This function performs JPEG
|
||||||
|
* decompression but leaves out the color conversion step, so a planar YUV
|
||||||
|
* image is generated instead of an RGB image. The padding of the planes in
|
||||||
|
* this image is the same as in the images generated by #tjEncodeYUV2(). Note
|
||||||
|
* that, if the width or height of the image is not an even multiple of the MCU
|
||||||
|
* block size (see #tjMCUWidth and #tjMCUHeight), then an intermediate buffer
|
||||||
|
* copy will be performed within TurboJPEG.
|
||||||
|
* <p>
|
||||||
|
* NOTE: Technically, the JPEG format uses the YCbCr colorspace, but per the
|
||||||
|
* convention of the digital video community, the TurboJPEG API uses "YUV" to
|
||||||
|
* refer to an image format consisting of Y, Cb, and Cr image planes.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG decompressor or transformer instance
|
||||||
|
* @param jpegBuf pointer to a buffer containing the JPEG image to decompress
|
||||||
|
* @param jpegSize size of the JPEG image (in bytes)
|
||||||
|
* @param dstBuf pointer to an image buffer that will receive the YUV image.
|
||||||
|
* Use #tjBufSizeYUV() to determine the appropriate size for this buffer
|
||||||
|
* based on the image width, height, and level of subsampling.
|
||||||
|
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
|
||||||
|
* "flags".
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
|
||||||
|
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TurboJPEG transformer instance.
|
||||||
|
*
|
||||||
|
* @return a handle to the newly-created instance, or NULL if an error
|
||||||
|
* occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT tjhandle DLLCALL tjInitTransform(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Losslessly transform a JPEG image into another JPEG image. Lossless
|
||||||
|
* transforms work by moving the raw coefficients from one JPEG image structure
|
||||||
|
* to another without altering the values of the coefficients. While this is
|
||||||
|
* typically faster than decompressing the image, transforming it, and
|
||||||
|
* re-compressing it, lossless transforms are not free. Each lossless
|
||||||
|
* transform requires reading and performing Huffman decoding on all of the
|
||||||
|
* coefficients in the source image, regardless of the size of the destination
|
||||||
|
* image. Thus, this function provides a means of generating multiple
|
||||||
|
* transformed images from the same source or applying multiple
|
||||||
|
* transformations simultaneously, in order to eliminate the need to read the
|
||||||
|
* source coefficients multiple times.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG transformer instance
|
||||||
|
* @param jpegBuf pointer to a buffer containing the JPEG image to transform
|
||||||
|
* @param jpegSize size of the JPEG image (in bytes)
|
||||||
|
* @param n the number of transformed JPEG images to generate
|
||||||
|
* @param dstBufs pointer to an array of n image buffers. <tt>dstBufs[i]</tt>
|
||||||
|
* will receive a JPEG image that has been transformed using the
|
||||||
|
* parameters in <tt>transforms[i]</tt>. TurboJPEG has the ability to
|
||||||
|
* reallocate the JPEG buffer to accommodate the size of the JPEG image.
|
||||||
|
* Thus, you can choose to:
|
||||||
|
* -# pre-allocate the JPEG buffer with an arbitrary size using
|
||||||
|
* #tjAlloc() and let TurboJPEG grow the buffer as needed,
|
||||||
|
* -# set <tt>dstBufs[i]</tt> to NULL to tell TurboJPEG to allocate the
|
||||||
|
* buffer for you, or
|
||||||
|
* -# pre-allocate the buffer to a "worst case" size determined by
|
||||||
|
* calling #tjBufSize() with the transformed or cropped width and
|
||||||
|
* height. This should ensure that the buffer never has to be
|
||||||
|
* re-allocated (setting #TJFLAG_NOREALLOC guarantees this.)
|
||||||
|
* .
|
||||||
|
* If you choose option 1, <tt>dstSizes[i]</tt> should be set to
|
||||||
|
* the size of your pre-allocated buffer. In any case, unless you have
|
||||||
|
* set #TJFLAG_NOREALLOC, you should always check <tt>dstBufs[i]</tt>
|
||||||
|
* upon return from this function, as it may have changed.
|
||||||
|
* @param dstSizes pointer to an array of n unsigned long variables that will
|
||||||
|
* receive the actual sizes (in bytes) of each transformed JPEG image.
|
||||||
|
* If <tt>dstBufs[i]</tt> points to a pre-allocated buffer, then
|
||||||
|
* <tt>dstSizes[i]</tt> should be set to the size of the buffer. Upon
|
||||||
|
* return, <tt>dstSizes[i]</tt> will contain the size of the JPEG image
|
||||||
|
* (in bytes.)
|
||||||
|
* @param transforms pointer to an array of n #tjtransform structures, each of
|
||||||
|
* which specifies the transform parameters and/or cropping region for
|
||||||
|
* the corresponding transformed output image.
|
||||||
|
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
|
||||||
|
* "flags".
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf,
|
||||||
|
unsigned long jpegSize, int n, unsigned char **dstBufs,
|
||||||
|
unsigned long *dstSizes, tjtransform *transforms, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a TurboJPEG compressor, decompressor, or transformer instance.
|
||||||
|
*
|
||||||
|
* @param handle a handle to a TurboJPEG compressor, decompressor or
|
||||||
|
* transformer instance
|
||||||
|
*
|
||||||
|
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int DLLCALL tjDestroy(tjhandle handle);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an image buffer for use with TurboJPEG. You should always use
|
||||||
|
* this function to allocate the JPEG destination buffer(s) for #tjCompress2()
|
||||||
|
* and #tjTransform() unless you are disabling automatic buffer
|
||||||
|
* (re)allocation (by setting #TJFLAG_NOREALLOC.)
|
||||||
|
*
|
||||||
|
* @param bytes the number of bytes to allocate
|
||||||
|
*
|
||||||
|
* @return a pointer to a newly-allocated buffer with the specified number of
|
||||||
|
* bytes
|
||||||
|
*
|
||||||
|
* @sa tjFree()
|
||||||
|
*/
|
||||||
|
DLLEXPORT unsigned char* DLLCALL tjAlloc(int bytes);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an image buffer previously allocated by TurboJPEG. You should always
|
||||||
|
* use this function to free JPEG destination buffer(s) that were automatically
|
||||||
|
* (re)allocated by #tjCompress2() or #tjTransform() or that were manually
|
||||||
|
* allocated using #tjAlloc().
|
||||||
|
*
|
||||||
|
* @param buffer address of the buffer to free
|
||||||
|
*
|
||||||
|
* @sa tjAlloc()
|
||||||
|
*/
|
||||||
|
DLLEXPORT void DLLCALL tjFree(unsigned char *buffer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a descriptive error message explaining why the last command failed.
|
||||||
|
*
|
||||||
|
* @return a descriptive error message explaining why the last command failed.
|
||||||
|
*/
|
||||||
|
DLLEXPORT char* DLLCALL tjGetErrorStr(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Backward compatibility functions and macros (nothing to see here) */
|
||||||
|
#define NUMSUBOPT TJ_NUMSAMP
|
||||||
|
#define TJ_444 TJSAMP_444
|
||||||
|
#define TJ_422 TJSAMP_422
|
||||||
|
#define TJ_420 TJSAMP_420
|
||||||
|
#define TJ_411 TJSAMP_420
|
||||||
|
#define TJ_GRAYSCALE TJSAMP_GRAY
|
||||||
|
|
||||||
|
#define TJ_BGR 1
|
||||||
|
#define TJ_BOTTOMUP TJFLAG_BOTTOMUP
|
||||||
|
#define TJ_FORCEMMX TJFLAG_FORCEMMX
|
||||||
|
#define TJ_FORCESSE TJFLAG_FORCESSE
|
||||||
|
#define TJ_FORCESSE2 TJFLAG_FORCESSE2
|
||||||
|
#define TJ_ALPHAFIRST 64
|
||||||
|
#define TJ_FORCESSE3 TJFLAG_FORCESSE3
|
||||||
|
#define TJ_FASTUPSAMPLE TJFLAG_FASTUPSAMPLE
|
||||||
|
#define TJ_YUV 512
|
||||||
|
|
||||||
|
DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
|
||||||
|
|
||||||
|
DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
|
||||||
|
int jpegSubsamp);
|
||||||
|
|
||||||
|
DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
|
||||||
|
int width, int pitch, int height, int pixelSize, unsigned char *dstBuf,
|
||||||
|
unsigned long *compressedSize, int jpegSubsamp, int jpegQual, int flags);
|
||||||
|
|
||||||
|
DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle,
|
||||||
|
unsigned char *srcBuf, int width, int pitch, int height, int pixelSize,
|
||||||
|
unsigned char *dstBuf, int subsamp, int flags);
|
||||||
|
|
||||||
|
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
|
||||||
|
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height);
|
||||||
|
|
||||||
|
DLLEXPORT int DLLCALL tjDecompress(tjhandle handle,
|
||||||
|
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
|
||||||
|
int width, int pitch, int height, int pixelSize, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
BIN
portlibs/lib/libturbojpeg.a
Normal file
BIN
portlibs/lib/libturbojpeg.a
Normal file
Binary file not shown.
@ -86,6 +86,7 @@ void WiiMovie::DeInit()
|
|||||||
Video.DeInit();
|
Video.DeInit();
|
||||||
if(vFile != NULL)
|
if(vFile != NULL)
|
||||||
fclose(vFile);
|
fclose(vFile);
|
||||||
|
VideoF.dealloc();
|
||||||
vFile = NULL;
|
vFile = NULL;
|
||||||
Frame = NULL;
|
Frame = NULL;
|
||||||
TexHandle.Cleanup(Buffer[0]);
|
TexHandle.Cleanup(Buffer[0]);
|
||||||
@ -110,7 +111,7 @@ bool WiiMovie::Play(bool loop)
|
|||||||
Playing = true;
|
Playing = true;
|
||||||
Buffer[0].thread = false;
|
Buffer[0].thread = false;
|
||||||
Buffer[1].thread = false;
|
Buffer[1].thread = false;
|
||||||
LWP_CreateThread(&ReadThread, UpdateThread, this, ThreadStack, 32768, 60);
|
LWP_CreateThread(&ReadThread, UpdateThread, this, ThreadStack, 32768, 63);
|
||||||
//gprintf("Reading frames thread started\n");
|
//gprintf("Reading frames thread started\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -153,20 +154,16 @@ void WiiMovie::LoadNextFrame()
|
|||||||
{
|
{
|
||||||
if(!vFile || !Playing)
|
if(!vFile || !Playing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VideoFrame VideoF;
|
|
||||||
Video.getCurrentFrame(VideoF);
|
Video.getCurrentFrame(VideoF);
|
||||||
|
if(!VideoF.data)
|
||||||
if(!VideoF.getData())
|
|
||||||
return;
|
return;
|
||||||
TexData *CurFrame = &Buffer[BufferPos];
|
TexData *CurFrame = &Buffer[BufferPos];
|
||||||
if(TexHandle.fromTHP(CurFrame, VideoF.getData(), VideoF.getWidth(), VideoF.getHeight()) == TE_OK)
|
if(TexHandle.fromTHP(CurFrame, VideoF.data, VideoF.getWidth(), VideoF.getHeight()) == TE_OK)
|
||||||
{
|
{
|
||||||
CurFrame->thread = true;
|
CurFrame->thread = true;
|
||||||
Frame = CurFrame;
|
Frame = CurFrame;
|
||||||
BufferPos ^= 1;
|
BufferPos ^= 1;
|
||||||
}
|
}
|
||||||
VideoF.dealloc();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiiMovie::Continue()
|
bool WiiMovie::Continue()
|
||||||
|
@ -30,6 +30,7 @@ protected:
|
|||||||
lwp_t ReadThread;
|
lwp_t ReadThread;
|
||||||
|
|
||||||
ThpVideoFile Video;
|
ThpVideoFile Video;
|
||||||
|
VideoFrame VideoF;
|
||||||
FILE *vFile;
|
FILE *vFile;
|
||||||
float fps;
|
float fps;
|
||||||
Timer PlayTime;
|
Timer PlayTime;
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
#include <cstring> //memcmp
|
#include <cstring> //memcmp
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <turbojpeg.h>
|
||||||
|
#include "gecko/gecko.hpp"
|
||||||
#include "gcvid.h"
|
#include "gcvid.h"
|
||||||
#include "loader/utils.h"
|
#include "loader/utils.h"
|
||||||
#include "memory/mem2.hpp"
|
#include "memory/mem2.hpp"
|
||||||
@ -268,11 +269,11 @@ void VideoFrame::resize(int width, int height)
|
|||||||
_w = width;
|
_w = width;
|
||||||
_h = height;
|
_h = height;
|
||||||
|
|
||||||
//24 bpp, 4 byte padding
|
//32 bpp, 4 byte padding
|
||||||
_p = 3*width;
|
_p = 4*width;
|
||||||
_p += (4 - _p%4)%4;
|
_p += (4 - _p%4)%4;
|
||||||
|
|
||||||
_data = (u8 *)MEM2_alloc(_p * _h);
|
data = (u8 *)MEM2_alloc(_p * _h);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoFrame::getWidth() const
|
int VideoFrame::getWidth() const
|
||||||
@ -284,40 +285,14 @@ int VideoFrame::getHeight() const
|
|||||||
int VideoFrame::getPitch() const
|
int VideoFrame::getPitch() const
|
||||||
{ return _p; }
|
{ return _p; }
|
||||||
|
|
||||||
u8* VideoFrame::getData()
|
|
||||||
{ return _data; }
|
|
||||||
|
|
||||||
const u8* VideoFrame::getData() const
|
|
||||||
{ return _data; }
|
|
||||||
|
|
||||||
void VideoFrame::dealloc()
|
void VideoFrame::dealloc()
|
||||||
{
|
{
|
||||||
if(_data != NULL)
|
if(data != NULL)
|
||||||
free(_data);
|
free(data);
|
||||||
_data = NULL;
|
data = NULL;
|
||||||
_w = _h = _p = 0;
|
_w = _h = _p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//swaps red and blue channel of a video frame
|
|
||||||
void swapRB(VideoFrame& f)
|
|
||||||
{
|
|
||||||
u8* currLine = f.getData();
|
|
||||||
|
|
||||||
int hyt = f.getHeight();
|
|
||||||
int pitch = f.getPitch();
|
|
||||||
|
|
||||||
for(int y = 0; y < hyt; ++y)
|
|
||||||
{
|
|
||||||
for(int x = 0, x2 = 2; x < pitch; x += 3, x2 += 3)
|
|
||||||
{
|
|
||||||
u8 t = currLine[x];
|
|
||||||
currLine[x] = currLine[x2];
|
|
||||||
currLine[x2] = t;
|
|
||||||
}
|
|
||||||
currLine += pitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FILETYPE
|
enum FILETYPE
|
||||||
{
|
{
|
||||||
THP, MTH, JPG,
|
THP, MTH, JPG,
|
||||||
@ -353,9 +328,6 @@ long getFilesize(FILE* f)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decodeJpeg(const u8* data, int size, VideoFrame& dest);
|
|
||||||
|
|
||||||
|
|
||||||
VideoFile::VideoFile(FILE* f)
|
VideoFile::VideoFile(FILE* f)
|
||||||
: loop(true), _f(f)
|
: loop(true), _f(f)
|
||||||
{}
|
{}
|
||||||
@ -395,9 +367,19 @@ int VideoFile::getMaxAudioSamples() const
|
|||||||
int VideoFile::getCurrentBuffer(s16*) const
|
int VideoFile::getCurrentBuffer(s16*) const
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
void VideoFile::loadFrame(VideoFrame& frame, const u8* data, int size) const
|
void VideoFile::loadFrame(VideoFrame& frame, const u8* src, int src_size)
|
||||||
{
|
{
|
||||||
decodeJpeg(data, size, frame);
|
//convert format so jpeglib understands it...
|
||||||
|
int start, end;
|
||||||
|
int newSize = countRequiredSize(src, src_size, start, end);
|
||||||
|
u8 *buff = (u8*)MEM2_alloc(newSize);
|
||||||
|
if(buff != NULL)
|
||||||
|
{
|
||||||
|
convertToRealJpeg(buff, src, src_size, start, end);
|
||||||
|
//...and feed it to jpeglib
|
||||||
|
decodeRealJpeg(buff, newSize, frame);
|
||||||
|
MEM2_free(buff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThpVideoFile::Init(FILE *f)
|
bool ThpVideoFile::Init(FILE *f)
|
||||||
@ -432,6 +414,13 @@ bool ThpVideoFile::Init(FILE *f)
|
|||||||
_currFrameData = (u8*)MEM2_alloc(_head.maxBufferSize); //include some padding
|
_currFrameData = (u8*)MEM2_alloc(_head.maxBufferSize); //include some padding
|
||||||
if(_currFrameData == NULL)
|
if(_currFrameData == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
_currFrameRealData = (u8*)MEM2_alloc(_head.maxBufferSize * 2); //worst case if a frame has 0xFF
|
||||||
|
if(_currFrameRealData == NULL)
|
||||||
|
{
|
||||||
|
gprintf("couldnt allocate %u bytes!\n", _head.maxBufferSize * 2);
|
||||||
|
MEM2_free(_currFrameData);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
loadNextFrame();
|
loadNextFrame();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -439,8 +428,11 @@ bool ThpVideoFile::Init(FILE *f)
|
|||||||
void ThpVideoFile::DeInit()
|
void ThpVideoFile::DeInit()
|
||||||
{
|
{
|
||||||
if(_currFrameData != NULL)
|
if(_currFrameData != NULL)
|
||||||
free(_currFrameData);
|
MEM2_free(_currFrameData);
|
||||||
_currFrameData = NULL;
|
_currFrameData = NULL;
|
||||||
|
if(_currFrameRealData != NULL)
|
||||||
|
MEM2_free(_currFrameRealData);
|
||||||
|
_currFrameRealData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ThpVideoFile::getWidth() const
|
int ThpVideoFile::getWidth() const
|
||||||
@ -479,7 +471,15 @@ bool ThpVideoFile::loadNextFrame(bool skip)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThpVideoFile::getCurrentFrame(VideoFrame& f) const
|
void ThpVideoFile::loadFrame(VideoFrame& frame, const u8* src, int src_size)
|
||||||
|
{
|
||||||
|
int start, end;
|
||||||
|
int newSize = countRequiredSize(src, src_size, start, end);
|
||||||
|
convertToRealJpeg(_currFrameRealData, src, src_size, start, end);
|
||||||
|
decodeRealJpeg(_currFrameRealData, newSize, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThpVideoFile::getCurrentFrame(VideoFrame& f)
|
||||||
{
|
{
|
||||||
int size = *(u32*)(_currFrameData + 8);
|
int size = *(u32*)(_currFrameData + 8);
|
||||||
loadFrame(f, _currFrameData + 4 * _numInts, size);
|
loadFrame(f, _currFrameData + 4 * _numInts, size);
|
||||||
@ -576,7 +576,7 @@ bool MthVideoFile::loadNextFrame(bool skip)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MthVideoFile::getCurrentFrame(VideoFrame& f) const
|
void MthVideoFile::getCurrentFrame(VideoFrame& f)
|
||||||
{
|
{
|
||||||
int size = _thisFrameSize;
|
int size = _thisFrameSize;
|
||||||
loadFrame(f, &_currFrameData[0] + 4, size - 4);
|
loadFrame(f, &_currFrameData[0] + 4, size - 4);
|
||||||
@ -601,10 +601,10 @@ int JpgVideoFile::getHeight() const
|
|||||||
int JpgVideoFile::getFrameCount() const
|
int JpgVideoFile::getFrameCount() const
|
||||||
{ return 1; }
|
{ return 1; }
|
||||||
|
|
||||||
void JpgVideoFile::getCurrentFrame(VideoFrame& f) const
|
void JpgVideoFile::getCurrentFrame(VideoFrame& f)
|
||||||
{
|
{
|
||||||
f.resize(_currFrame.getWidth(), _currFrame.getHeight());
|
f.resize(_currFrame.getWidth(), _currFrame.getHeight());
|
||||||
memcpy(f.getData(), _currFrame.getData(),f.getPitch()*f.getHeight());
|
memcpy(f.data, _currFrame.data,f.getPitch()*f.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFile* openVideo(const string& fileName)
|
VideoFile* openVideo(const string& fileName)
|
||||||
@ -650,37 +650,37 @@ void closeVideo(VideoFile*& vf)
|
|||||||
u8 endBytesThp[] = { 0xff, 0xd9, 0, 0 }; //used in thp files
|
u8 endBytesThp[] = { 0xff, 0xd9, 0, 0 }; //used in thp files
|
||||||
u8 endBytesMth[] = { 0xff, 0xd9, 0xff, 0 }; //used in mth files
|
u8 endBytesMth[] = { 0xff, 0xd9, 0xff, 0 }; //used in mth files
|
||||||
|
|
||||||
int countRequiredSize(const u8* data, int size, int& start, int& end)
|
int VideoFile::countRequiredSize(const u8* src, int src_size, int& start, int& end)
|
||||||
{
|
{
|
||||||
start = 2*size;
|
start = 2*src_size;
|
||||||
end = size;
|
end = src_size;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for(j = size - 1; data[j] == 0; --j)
|
for(j = src_size - 1; src[j] == 0; --j)
|
||||||
; //search end of data
|
; //search end of data
|
||||||
|
|
||||||
if(data[j] == 0xd9) //thp file
|
if(src[j] == 0xd9) //thp file
|
||||||
end = j - 1;
|
end = j - 1;
|
||||||
else if(data[j] == 0xff) //mth file
|
else if(src[j] == 0xff) //mth file
|
||||||
end = j - 2;
|
end = j - 2;
|
||||||
|
|
||||||
for(int i = 0; i < end; ++i)
|
for(int i = 0; i < end; ++i)
|
||||||
{
|
{
|
||||||
if(data[i] == 0xff)
|
if(src[i] == 0xff)
|
||||||
{
|
{
|
||||||
//if i == srcSize - 1, then this would normally overrun src - that's why 4 padding
|
//if i == srcSize - 1, then this would normally overrun src - that's why 4 padding
|
||||||
//bytes are included at the end of src
|
//bytes are included at the end of src
|
||||||
if(data[i + 1] == 0xda && start == 2*size)
|
if(src[i + 1] == 0xda && start == 2*src_size)
|
||||||
start = i;
|
start = i;
|
||||||
if(i > start)
|
if(i > start)
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return size + count;
|
return src_size + count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void convertToRealJpeg(u8* dest, const u8* src, int srcSize, int start, int end)
|
void VideoFile::convertToRealJpeg(u8* dest, const u8* src, int srcSize, int start, int end)
|
||||||
{
|
{
|
||||||
int di = 0;
|
int di = 0;
|
||||||
for(int i = 0; i < srcSize; ++i, ++di)
|
for(int i = 0; i < srcSize; ++i, ++di)
|
||||||
@ -696,135 +696,22 @@ void convertToRealJpeg(u8* dest, const u8* src, int srcSize, int start, int end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void decodeJpeg(const u8* data, int size, VideoFrame& dest)
|
|
||||||
{
|
|
||||||
//convert format so jpeglib understands it...
|
|
||||||
int start, end;
|
|
||||||
int newSize = countRequiredSize(data, size, start, end);
|
|
||||||
u8 *buff = (u8*)MEM2_alloc(newSize);
|
|
||||||
convertToRealJpeg(buff, data, size, start, end);
|
|
||||||
|
|
||||||
//...and feed it to jpeglib
|
|
||||||
decodeRealJpeg(buff, newSize, dest);
|
|
||||||
MEM2_free(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <jpeglib.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
//the following functions are needed to let
|
|
||||||
//libjpeg read from memory instead of from a file...
|
|
||||||
//it's a little clumsy to do :-|
|
|
||||||
const u8* g_jpegBuffer;
|
|
||||||
int g_jpegSize;
|
|
||||||
bool g_isLoading = false;
|
bool g_isLoading = false;
|
||||||
|
|
||||||
void jpegInitSource(j_decompress_ptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
boolean jpegFillInputBuffer(j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
cinfo->src->next_input_byte = g_jpegBuffer;
|
|
||||||
cinfo->src->bytes_in_buffer = g_jpegSize;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
|
|
||||||
{
|
|
||||||
cinfo->src->next_input_byte += num_bytes;
|
|
||||||
cinfo->src->bytes_in_buffer -= num_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean jpegResyncToRestart(j_decompress_ptr cinfo, int desired)
|
|
||||||
{
|
|
||||||
jpeg_resync_to_restart(cinfo, desired);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jpegTermSource(j_decompress_ptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void jpegErrorHandler(j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
(*cinfo->err->format_message)(cinfo, buff);
|
|
||||||
//MessageBox(g_hWnd, buff, "JpegLib error:", MB_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void decodeRealJpeg(const u8* data, int size, VideoFrame& dest, bool fancy)
|
void decodeRealJpeg(const u8* data, int size, VideoFrame& dest, bool fancy)
|
||||||
{
|
{
|
||||||
if(g_isLoading)
|
if(g_isLoading)
|
||||||
return;
|
return;
|
||||||
g_isLoading = true;
|
g_isLoading = true;
|
||||||
|
|
||||||
//decompressor state
|
/* init turbojpeg */
|
||||||
jpeg_decompress_struct cinfo;
|
u8 *src = (u8*)data;
|
||||||
jpeg_error_mgr errorMgr;
|
int jpegSubsamp, width, height;
|
||||||
|
tjhandle _jpegDecompressor = tjInitDecompress();
|
||||||
//read from memory manager
|
tjDecompressHeader2(_jpegDecompressor, src, size, &width, &height, &jpegSubsamp);
|
||||||
jpeg_source_mgr sourceMgr;
|
/* decode to buffer */
|
||||||
|
dest.resize(width, height);
|
||||||
cinfo.err = jpeg_std_error(&errorMgr);
|
tjDecompress2(_jpegDecompressor, src, size, dest.data, width, 0, height,
|
||||||
errorMgr.error_exit = jpegErrorHandler;
|
TJPF_RGBA, fancy ? TJFLAG_ACCURATEDCT : (TJFLAG_FASTDCT | TJFLAG_FASTUPSAMPLE));
|
||||||
|
tjDestroy(_jpegDecompressor);
|
||||||
jpeg_create_decompress(&cinfo);
|
|
||||||
|
|
||||||
//setup read-from-memory
|
|
||||||
g_jpegBuffer = data;
|
|
||||||
g_jpegSize = size;
|
|
||||||
sourceMgr.bytes_in_buffer = size;
|
|
||||||
sourceMgr.next_input_byte = data;
|
|
||||||
sourceMgr.init_source = jpegInitSource;
|
|
||||||
sourceMgr.fill_input_buffer = jpegFillInputBuffer;
|
|
||||||
sourceMgr.skip_input_data = jpegSkipInputData;
|
|
||||||
sourceMgr.resync_to_restart = jpegResyncToRestart;
|
|
||||||
sourceMgr.term_source = jpegTermSource;
|
|
||||||
cinfo.src = &sourceMgr;
|
|
||||||
|
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
|
||||||
if(fancy)
|
|
||||||
{
|
|
||||||
cinfo.do_fancy_upsampling = TRUE;
|
|
||||||
cinfo.do_block_smoothing = TRUE;
|
|
||||||
cinfo.dct_method = JDCT_ISLOW;
|
|
||||||
jpeg_start_decompress(&cinfo);
|
|
||||||
dest.resize(ALIGN(4, cinfo.output_width), ALIGN(4, cinfo.output_height));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cinfo.do_fancy_upsampling = FALSE;
|
|
||||||
cinfo.do_block_smoothing = FALSE;
|
|
||||||
jpeg_start_decompress(&cinfo);
|
|
||||||
dest.resize(cinfo.output_width, cinfo.output_height);
|
|
||||||
}
|
|
||||||
if(cinfo.num_components == 3)
|
|
||||||
{
|
|
||||||
int y = 0;
|
|
||||||
while(cinfo.output_scanline < cinfo.output_height)
|
|
||||||
{
|
|
||||||
//invert image because windows wants it downside up
|
|
||||||
u8* destBuffer = &dest.getData()[(dest.getHeight() - y - 1)*dest.getPitch()];
|
|
||||||
|
|
||||||
//NO idea why jpeglib wants a pointer to a pointer
|
|
||||||
jpeg_read_scanlines(&cinfo, &destBuffer, 1);
|
|
||||||
++y;
|
|
||||||
}
|
|
||||||
|
|
||||||
//jpeglib gives an error in jpeg_finish_decompress() if no all
|
|
||||||
//scanlines are read by the application... :-|
|
|
||||||
//(but because we read all scanlines, it's not really needed)
|
|
||||||
cinfo.output_scanline = cinfo.output_height;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//MessageBox(g_hWnd, "Only RGB videos are currently supported.", "oops?", MB_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
g_isLoading = false;
|
g_isLoading = false;
|
||||||
}
|
}
|
||||||
|
@ -186,21 +186,19 @@ struct MthHeader
|
|||||||
class VideoFrame
|
class VideoFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VideoFrame() : _data(NULL), _w(0), _h(0), _p(0) { };
|
VideoFrame() : data(NULL), _w(0), _h(0), _p(0) { };
|
||||||
~VideoFrame() { };
|
~VideoFrame() { };
|
||||||
|
|
||||||
|
u8 *data; //texdata style
|
||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
|
|
||||||
int getWidth() const;
|
int getWidth() const;
|
||||||
int getHeight() const;
|
int getHeight() const;
|
||||||
int getPitch() const;
|
int getPitch() const;
|
||||||
u8* getData();
|
|
||||||
const u8* getData() const;
|
|
||||||
|
|
||||||
void dealloc();
|
void dealloc();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u8* _data;
|
|
||||||
int _w;
|
int _w;
|
||||||
int _h;
|
int _h;
|
||||||
int _p; //pitch in bytes
|
int _p; //pitch in bytes
|
||||||
@ -210,9 +208,6 @@ class VideoFrame
|
|||||||
VideoFrame& operator=(const VideoFrame& f);
|
VideoFrame& operator=(const VideoFrame& f);
|
||||||
};
|
};
|
||||||
|
|
||||||
//swaps red and blue channel of a video frame
|
|
||||||
void swapRB(VideoFrame& f);
|
|
||||||
|
|
||||||
|
|
||||||
class VideoFile
|
class VideoFile
|
||||||
{
|
{
|
||||||
@ -229,7 +224,7 @@ class VideoFile
|
|||||||
|
|
||||||
virtual bool loadNextFrame(bool skip = false) = 0;
|
virtual bool loadNextFrame(bool skip = false) = 0;
|
||||||
|
|
||||||
virtual void getCurrentFrame(VideoFrame& frame) const = 0;
|
virtual void getCurrentFrame(VideoFrame& frame) = 0;
|
||||||
|
|
||||||
//sound support:
|
//sound support:
|
||||||
virtual bool hasSound() const;
|
virtual bool hasSound() const;
|
||||||
@ -244,8 +239,10 @@ class VideoFile
|
|||||||
FILE* _f;
|
FILE* _f;
|
||||||
|
|
||||||
//void loadFrame(long offset, int size);
|
//void loadFrame(long offset, int size);
|
||||||
void loadFrame(VideoFrame& frame, const u8* data, int size) const;
|
virtual void loadFrame(VideoFrame& frame, const u8* src, int src_size);
|
||||||
|
|
||||||
|
int countRequiredSize(const u8* src, int src_size, int& start, int& end);
|
||||||
|
void convertToRealJpeg(u8* dest, const u8* src, int srcSize, int start, int end);
|
||||||
};
|
};
|
||||||
|
|
||||||
VideoFile* openVideo(const std::string& fileName);
|
VideoFile* openVideo(const std::string& fileName);
|
||||||
@ -269,14 +266,14 @@ class ThpVideoFile : public VideoFile
|
|||||||
|
|
||||||
virtual bool loadNextFrame(bool skip = false);
|
virtual bool loadNextFrame(bool skip = false);
|
||||||
|
|
||||||
virtual void getCurrentFrame(VideoFrame& frame) const;
|
virtual void getCurrentFrame(VideoFrame& frame);
|
||||||
|
|
||||||
virtual bool hasSound() const;
|
virtual bool hasSound() const;
|
||||||
virtual int getNumChannels() const;
|
virtual int getNumChannels() const;
|
||||||
virtual int getFrequency() const;
|
virtual int getFrequency() const;
|
||||||
virtual int getMaxAudioSamples() const;
|
virtual int getMaxAudioSamples() const;
|
||||||
virtual int getCurrentBuffer(s16* data) const;
|
virtual int getCurrentBuffer(s16* data) const;
|
||||||
|
virtual void loadFrame(VideoFrame& frame, const u8* src, int src_size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ThpHeader _head;
|
ThpHeader _head;
|
||||||
@ -289,6 +286,7 @@ class ThpVideoFile : public VideoFile
|
|||||||
int _nextFrameOffset;
|
int _nextFrameOffset;
|
||||||
int _nextFrameSize;
|
int _nextFrameSize;
|
||||||
u8 *_currFrameData;
|
u8 *_currFrameData;
|
||||||
|
u8 *_currFrameRealData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MthVideoFile : public VideoFile
|
class MthVideoFile : public VideoFile
|
||||||
@ -305,7 +303,7 @@ class MthVideoFile : public VideoFile
|
|||||||
|
|
||||||
virtual bool loadNextFrame(bool skip = false);
|
virtual bool loadNextFrame(bool skip = false);
|
||||||
|
|
||||||
virtual void getCurrentFrame(VideoFrame& frame) const;
|
virtual void getCurrentFrame(VideoFrame& frame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MthHeader _head;
|
MthHeader _head;
|
||||||
@ -327,7 +325,7 @@ class JpgVideoFile : public VideoFile
|
|||||||
virtual int getFrameCount() const;
|
virtual int getFrameCount() const;
|
||||||
|
|
||||||
virtual bool loadNextFrame(bool skip = false) { return skip; }
|
virtual bool loadNextFrame(bool skip = false) { return skip; }
|
||||||
virtual void getCurrentFrame(VideoFrame& frame) const;
|
virtual void getCurrentFrame(VideoFrame& frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoFrame _currFrame;
|
VideoFrame _currFrame;
|
||||||
|
@ -41,30 +41,6 @@ static inline u32 coordsRGB565(u32 x, u32 y, u32 w)
|
|||||||
return (((y >> 2) * (w >> 2) + (x >> 2)) << 4) + ((y & 3) << 2) + (x & 3);
|
return (((y >> 2) * (w >> 2) + (x >> 2)) << 4) + ((y & 3) << 2) + (x & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _convertToFlippedRGBA(u8 *dst, const u8 *src, u32 width, u32 height)
|
|
||||||
{
|
|
||||||
for(u32 block = 0; block < height; block += 4)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < width; i += 4)
|
|
||||||
{
|
|
||||||
for(u32 c = 0; c < 4; ++c)
|
|
||||||
{
|
|
||||||
for(u32 rgb = 0; rgb < 4; ++rgb)
|
|
||||||
{
|
|
||||||
u32 y = height - 1 - (c + block);
|
|
||||||
u32 x = rgb + i;
|
|
||||||
u32 dst_offset = (x + y * width) * 4;
|
|
||||||
u32 src_offset = (x + ((block + c) * width)) * 3;
|
|
||||||
/* RGB */
|
|
||||||
memcpy(&dst[dst_offset], &src[src_offset], 3);
|
|
||||||
/* Alpha */
|
|
||||||
dst[dst_offset + 3] = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _convertToRGBA(u8 *dst, const u8 *src, u32 width, u32 height)
|
static inline void _convertToRGBA(u8 *dst, const u8 *src, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
for (u32 y = 0; y < height; ++y)
|
for (u32 y = 0; y < height; ++y)
|
||||||
@ -276,28 +252,7 @@ TexErr STexture::fromTHP(TexData *dest, const u8 *src, u32 w, u32 h)
|
|||||||
return TE_NOMEM;
|
return TE_NOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(u32 block = 0; block < dest->height; block += 4)
|
_convertToRGBA8(dest->data, src, w, h);
|
||||||
{
|
|
||||||
for(u32 i = 0; i < dest->width; i += 4)
|
|
||||||
{
|
|
||||||
for(u32 c = 0; c < 4; ++c)
|
|
||||||
{
|
|
||||||
for(u32 argb = 0; argb < 4; ++argb)
|
|
||||||
{
|
|
||||||
u32 y = h - 1 - (c + block);
|
|
||||||
u32 x = argb + i;
|
|
||||||
u32 src_offset = ((i + argb) + ((block + c) * dest->width)) * 3;
|
|
||||||
u32 dst_offset = coordsRGBA8(x, y, dest->width);
|
|
||||||
/* Alpha */
|
|
||||||
dest->data[dst_offset] = 0xFF;
|
|
||||||
/* RGB */
|
|
||||||
dest->data[dst_offset + 1] = src[src_offset];
|
|
||||||
dest->data[dst_offset + 32] = src[src_offset + 1];
|
|
||||||
dest->data[dst_offset + 33] = src[src_offset + 2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DCFlushRange(dest->data, dest->dataSize);
|
DCFlushRange(dest->data, dest->dataSize);
|
||||||
return TE_OK;
|
return TE_OK;
|
||||||
}
|
}
|
||||||
@ -309,26 +264,15 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size,
|
|||||||
// Decode our JPG to raw
|
// Decode our JPG to raw
|
||||||
VideoFrame VideoF;
|
VideoFrame VideoF;
|
||||||
decodeRealJpeg(buffer, buffer_size, VideoF, true);
|
decodeRealJpeg(buffer, buffer_size, VideoF, true);
|
||||||
if(!VideoF.getData())
|
if(!VideoF.data)
|
||||||
|
{
|
||||||
|
VideoF.dealloc();
|
||||||
return TE_ERROR;
|
return TE_ERROR;
|
||||||
dest.data = VideoF.getData();
|
}
|
||||||
|
dest.data = NULL;
|
||||||
dest.width = VideoF.getWidth();
|
dest.width = VideoF.getWidth();
|
||||||
dest.height = VideoF.getHeight();
|
dest.height = VideoF.getHeight();
|
||||||
|
|
||||||
// Convert our raw stuff to a usable format
|
|
||||||
u8 *rawData = (u8*)MEM2_alloc(dest.width * dest.height * 4);
|
|
||||||
if(rawData == NULL)
|
|
||||||
{
|
|
||||||
Cleanup(dest);
|
|
||||||
return TE_NOMEM;
|
|
||||||
}
|
|
||||||
_convertToFlippedRGBA(rawData, dest.data, dest.width, dest.height);
|
|
||||||
|
|
||||||
//Free our raw stuff
|
|
||||||
VideoF.dealloc();
|
|
||||||
dest.data = NULL;
|
|
||||||
|
|
||||||
//Let the real work begin
|
|
||||||
u8 maxLODTmp = 0;
|
u8 maxLODTmp = 0;
|
||||||
u8 minLODTmp = 0;
|
u8 minLODTmp = 0;
|
||||||
u32 baseWidth;
|
u32 baseWidth;
|
||||||
@ -349,10 +293,11 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size,
|
|||||||
_calcMipMaps(maxLODTmp, minLODTmp, baseWidth, baseHeight, dest.width, dest.height, minMipSize, maxMipSize);
|
_calcMipMaps(maxLODTmp, minLODTmp, baseWidth, baseHeight, dest.width, dest.height, minMipSize, maxMipSize);
|
||||||
if (maxLODTmp > 0)
|
if (maxLODTmp > 0)
|
||||||
{
|
{
|
||||||
rawData = _genMipMaps(rawData, dest.width, dest.height, maxLODTmp, baseWidth, baseHeight);
|
u8 *rawData = _genMipMaps(VideoF.data, dest.width, dest.height, maxLODTmp, baseWidth, baseHeight);
|
||||||
if(rawData == NULL)
|
if(rawData == NULL)
|
||||||
{
|
{
|
||||||
Cleanup(dest);
|
Cleanup(dest);
|
||||||
|
VideoF.dealloc();
|
||||||
return TE_NOMEM;
|
return TE_NOMEM;
|
||||||
}
|
}
|
||||||
u32 newWidth = baseWidth;
|
u32 newWidth = baseWidth;
|
||||||
@ -368,6 +313,7 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size,
|
|||||||
{
|
{
|
||||||
Cleanup(dest);
|
Cleanup(dest);
|
||||||
free(rawData);
|
free(rawData);
|
||||||
|
VideoF.dealloc();
|
||||||
return TE_NOMEM;
|
return TE_NOMEM;
|
||||||
}
|
}
|
||||||
u32 nWidth = newWidth;
|
u32 nWidth = newWidth;
|
||||||
@ -395,6 +341,7 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size,
|
|||||||
nWidth >>= 1;
|
nWidth >>= 1;
|
||||||
nHeight >>= 1;
|
nHeight >>= 1;
|
||||||
}
|
}
|
||||||
|
free(rawData);
|
||||||
dest.maxLOD = maxLODTmp - minLODTmp;
|
dest.maxLOD = maxLODTmp - minLODTmp;
|
||||||
dest.width = newWidth;
|
dest.width = newWidth;
|
||||||
dest.height = newHeight;
|
dest.height = newHeight;
|
||||||
@ -406,24 +353,24 @@ TexErr STexture::fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size,
|
|||||||
if(dest.data == NULL)
|
if(dest.data == NULL)
|
||||||
{
|
{
|
||||||
Cleanup(dest);
|
Cleanup(dest);
|
||||||
free(rawData);
|
VideoF.dealloc();
|
||||||
return TE_NOMEM;
|
return TE_NOMEM;
|
||||||
}
|
}
|
||||||
switch(f)
|
switch(f)
|
||||||
{
|
{
|
||||||
case GX_TF_RGBA8:
|
case GX_TF_RGBA8:
|
||||||
_convertToRGBA8(dest.data, rawData, dest.width, dest.height);
|
_convertToRGBA8(dest.data, VideoF.data, dest.width, dest.height);
|
||||||
break;
|
break;
|
||||||
case GX_TF_RGB565:
|
case GX_TF_RGB565:
|
||||||
_convertToRGB565(dest.data, rawData, dest.width, dest.height);
|
_convertToRGB565(dest.data, VideoF.data, dest.width, dest.height);
|
||||||
break;
|
break;
|
||||||
case GX_TF_CMPR:
|
case GX_TF_CMPR:
|
||||||
_convertToCMPR(dest.data, rawData, dest.width, dest.height);
|
_convertToCMPR(dest.data, VideoF.data, dest.width, dest.height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VideoF.dealloc();
|
||||||
DCFlushRange(dest.data, dest.dataSize);
|
DCFlushRange(dest.data, dest.dataSize);
|
||||||
free(rawData);
|
|
||||||
return TE_OK;
|
return TE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,7 +653,7 @@ void STexture::_calcMipMaps(u8 &maxLOD, u8 &minLOD, u32 &lod0Width, u32 &lod0Hei
|
|||||||
maxLOD = minLOD;
|
maxLOD = minLOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *STexture::_genMipMaps(u8 *src, u32 width, u32 height, u8 maxLOD, u32 lod0Width, u32 lod0Height)
|
u8 *STexture::_genMipMaps(u8 *&src, u32 width, u32 height, u8 maxLOD, u32 lod0Width, u32 lod0Height)
|
||||||
{
|
{
|
||||||
u32 bufSize = fixGX_GetTexBufferSize(lod0Width, lod0Height, GX_TF_RGBA8, GX_TRUE, maxLOD);
|
u32 bufSize = fixGX_GetTexBufferSize(lod0Width, lod0Height, GX_TF_RGBA8, GX_TRUE, maxLOD);
|
||||||
u8 *dstData = (u8*)MEM2_alloc(bufSize);
|
u8 *dstData = (u8*)MEM2_alloc(bufSize);
|
||||||
|
@ -366,6 +366,26 @@ void CMenu::_cleanupVideo()
|
|||||||
movie.DeInit();
|
movie.DeInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *getVideoPath(const string &videoDir, const char *videoId)
|
||||||
|
{
|
||||||
|
const char *coverDir = m_plugin.GetCoverFolderName(CoverFlow.getHdr()->settings[0]);
|
||||||
|
const char *videoPath = NULL;
|
||||||
|
if(coverDir == NULL || strlen(coverDir) == 0)
|
||||||
|
videoPath = fmt("%s/%s", videoDir.c_str(), videoId);
|
||||||
|
else
|
||||||
|
videoPath = fmt("%s/%s/%s", videoDir.c_str(), coverDir, videoId);
|
||||||
|
return videoPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *getVideoDefaultPath(const string &videoDir)
|
||||||
|
{
|
||||||
|
char PluginMagicWord[9];
|
||||||
|
memset(PluginMagicWord, 0, sizeof(PluginMagicWord));
|
||||||
|
strncpy(PluginMagicWord, fmt("%08x", CoverFlow.getHdr()->settings[0]), 8);
|
||||||
|
const char *videoPath = fmt("%s/%s", videoDir.c_str(), PluginMagicWord);
|
||||||
|
return videoPath;
|
||||||
|
}
|
||||||
|
|
||||||
bool CMenu::_startVideo()
|
bool CMenu::_startVideo()
|
||||||
{
|
{
|
||||||
char curId3[4];
|
char curId3[4];
|
||||||
@ -376,15 +396,21 @@ bool CMenu::_startVideo()
|
|||||||
memcpy(curId3, CoverFlow.getId(), 3);
|
memcpy(curId3, CoverFlow.getId(), 3);
|
||||||
videoId = curId3;
|
videoId = curId3;
|
||||||
}
|
}
|
||||||
const char *videoPath = fmt("%s/%s.thp", m_videoDir.c_str(), videoId);
|
const char *videoPath = getVideoPath(m_videoDir, videoId);
|
||||||
if(fsop_FileExist(videoPath))
|
const char *THP_Path = fmt("%s.thp", videoPath);
|
||||||
|
if(!fsop_FileExist(THP_Path) && m_current_view == COVERFLOW_PLUGIN)
|
||||||
{
|
{
|
||||||
m_gameSound.Stop();
|
videoPath = getVideoDefaultPath(m_videoDir);
|
||||||
|
THP_Path = fmt("%s.thp", videoPath);
|
||||||
|
}
|
||||||
|
if(fsop_FileExist(THP_Path))
|
||||||
|
{
|
||||||
|
m_gameSound.FreeMemory();
|
||||||
MusicPlayer.Stop();
|
MusicPlayer.Stop();
|
||||||
m_banner.SetShowBanner(false);
|
m_banner.SetShowBanner(false);
|
||||||
/* Lets play the movie */
|
/* Lets play the movie */
|
||||||
movie.Init(videoPath);
|
movie.Init(THP_Path);
|
||||||
m_gameSound.Load(fmt("%s/%s.ogg", m_videoDir.c_str(), videoId));
|
m_gameSound.Load(fmt("%s.ogg", videoPath));
|
||||||
m_gameSound.SetVolume(m_cfg.getInt("GENERAL", "sound_volume_bnr", 255));
|
m_gameSound.SetVolume(m_cfg.getInt("GENERAL", "sound_volume_bnr", 255));
|
||||||
m_video_playing = true;
|
m_video_playing = true;
|
||||||
m_gameSound.Play();
|
m_gameSound.Play();
|
||||||
@ -400,7 +426,9 @@ void CMenu::_game(bool launch)
|
|||||||
m_zoom_banner = m_cfg.getBool(_domainFromView(), "show_full_banner", false);
|
m_zoom_banner = m_cfg.getBool(_domainFromView(), "show_full_banner", false);
|
||||||
if(NoGameID(CoverFlow.getHdr()->type))
|
if(NoGameID(CoverFlow.getHdr()->type))
|
||||||
{
|
{
|
||||||
m_zoom_banner = m_zoom_banner && fsop_FileExist(fmt("%s/%s.thp", m_videoDir.c_str(), CoverFlow.getPathId(CoverFlow.getHdr())));
|
bool video_available = (m_current_view == COVERFLOW_PLUGIN && fsop_FileExist(fmt("%s.thp", getVideoDefaultPath(m_videoDir)))) ||
|
||||||
|
fsop_FileExist(fmt("%s.thp", getVideoPath(m_videoDir, CoverFlow.getPathId(CoverFlow.getHdr()))));
|
||||||
|
m_zoom_banner = m_zoom_banner && video_available;
|
||||||
m_cfg.setBool(_domainFromView(), "show_full_banner", m_zoom_banner);
|
m_cfg.setBool(_domainFromView(), "show_full_banner", m_zoom_banner);
|
||||||
}
|
}
|
||||||
currentMoviePos = (m_zoom_banner ? zoomedMoviePos : normalMoviePos);
|
currentMoviePos = (m_zoom_banner ? zoomedMoviePos : normalMoviePos);
|
||||||
|
Loading…
Reference in New Issue
Block a user