-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:
fix94.1 2014-03-22 21:32:40 +00:00
parent fad956006c
commit bbf0091922
14 changed files with 1062 additions and 2067 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View 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

Binary file not shown.

View File

@ -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()

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);

View File

@ -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);