add VFS destination plugin for jpeg-6b (allows writing out images as JPG)
removed unnecessary SIZEOF macro (replaced with sizeof) This was SVN commit r1985.
This commit is contained in:
parent
19b3d2d388
commit
eab8c2957a
@ -1,9 +1,3 @@
|
|||||||
#include "precompiled.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* jmemdatasrc.c (adapted from IJG jdatasrc.c)
|
* jmemdatasrc.c (adapted from IJG jdatasrc.c)
|
||||||
*
|
*
|
||||||
@ -16,12 +10,21 @@ extern "C" {
|
|||||||
* IMPORTANT: we assume that JOCTET is 8 bits.
|
* IMPORTANT: we assume that JOCTET is 8 bits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "lib/res/vfs.h"
|
||||||
|
|
||||||
|
|
||||||
|
// must come before jpeg-6b headers.
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
#include "jerror.h"
|
#include "jerror.h"
|
||||||
|
|
||||||
// (Simon) Macros from jinclude.h, which isn't installed by default on my system
|
|
||||||
#define SIZEOF(_a) ((size_t) sizeof(_a))
|
|
||||||
|
|
||||||
/* Expanded data source object for memory input */
|
/* Expanded data source object for memory input */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -159,12 +162,13 @@ GLOBAL(void) jpeg_mem_src(j_decompress_ptr cinfo, void* p, size_t size)
|
|||||||
* by calling jpeg_mem_src only before the first one.
|
* by calling jpeg_mem_src only before the first one.
|
||||||
* This makes it unsafe to use this manager and a different source
|
* This makes it unsafe to use this manager and a different source
|
||||||
* manager serially with the same JPEG object. Caveat programmer.
|
* manager serially with the same JPEG object. Caveat programmer.
|
||||||
|
*/
|
||||||
|
|
||||||
/* first time for this JPEG object? */
|
/* first time for this JPEG object? */
|
||||||
if(!cinfo->src)
|
if(!cinfo->src)
|
||||||
cinfo->src = (struct jpeg_source_mgr*)
|
cinfo->src = (struct jpeg_source_mgr*)
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
|
||||||
SIZEOF(MemSrcMgr));
|
sizeof(MemSrcMgr));
|
||||||
/* (takes care of raising error if out of memory) */
|
/* (takes care of raising error if out of memory) */
|
||||||
|
|
||||||
src = (SrcPtr)cinfo->src;
|
src = (SrcPtr)cinfo->src;
|
||||||
@ -182,6 +186,192 @@ GLOBAL(void) jpeg_mem_src(j_decompress_ptr cinfo, void* p, size_t size)
|
|||||||
src->pub.next_input_byte = (JOCTET*)p;
|
src->pub.next_input_byte = (JOCTET*)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Expanded data destination object for VFS output */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct jpeg_destination_mgr pub; /* public fields */
|
||||||
|
|
||||||
|
Handle hf;
|
||||||
|
JOCTET* buf;
|
||||||
|
// jpeg-6b interface needs a memory buffer
|
||||||
|
} VfsDstMgr;
|
||||||
|
|
||||||
|
typedef VfsDstMgr* DstPtr;
|
||||||
|
|
||||||
|
#define OUTPUT_BUF_SIZE 16*KiB /* choose an efficiently writeable size */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize destination --- called by jpeg_start_compress
|
||||||
|
* before any data is actually written.
|
||||||
|
*/
|
||||||
|
|
||||||
|
METHODDEF(void) init_destination(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
DstPtr dst = (DstPtr)cinfo->dest;
|
||||||
|
|
||||||
|
/* Allocate the output buffer --- it will be released when done with image */
|
||||||
|
dst->buf = (JOCTET*)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||||
|
OUTPUT_BUF_SIZE * sizeof(JOCTET));
|
||||||
|
|
||||||
|
dst->pub.next_output_byte = dst->buf;
|
||||||
|
dst->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Empty the output buffer --- called whenever buffer fills up.
|
||||||
|
*
|
||||||
|
* In typical applications, this should write the entire output buffer
|
||||||
|
* (ignoring the current state of next_output_byte & free_in_buffer),
|
||||||
|
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||||
|
* indicating that the buffer has been dumped.
|
||||||
|
*
|
||||||
|
* In applications that need to be able to suspend compression due to output
|
||||||
|
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
|
||||||
|
* In this situation, the compressor will return to its caller (possibly with
|
||||||
|
* an indication that it has not accepted all the supplied scanlines). The
|
||||||
|
* application should resume compression after it has made more room in the
|
||||||
|
* output buffer. Note that there are substantial restrictions on the use of
|
||||||
|
* suspension --- see the documentation.
|
||||||
|
*
|
||||||
|
* When suspending, the compressor will back up to a convenient restart point
|
||||||
|
* (typically the start of the current MCU). next_output_byte & free_in_buffer
|
||||||
|
* indicate where the restart point will be if the current call returns FALSE.
|
||||||
|
* Data beyond this point will be regenerated after resumption, so do not
|
||||||
|
* write it out when emptying the buffer externally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
DstPtr dst = (DstPtr)cinfo->dest;
|
||||||
|
|
||||||
|
// writing out OUTPUT_BUF_SIZE-dst->pub.free_in_buffer bytes
|
||||||
|
// sounds reasonable, but make for broken output.
|
||||||
|
if(vfs_io(dst->hf, OUTPUT_BUF_SIZE, (void**)&dst->buf) != OUTPUT_BUF_SIZE)
|
||||||
|
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||||
|
|
||||||
|
dst->pub.next_output_byte = dst->buf;
|
||||||
|
dst->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terminate destination --- called by jpeg_finish_compress
|
||||||
|
* after all data has been written. Usually needs to flush buffer.
|
||||||
|
*
|
||||||
|
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||||
|
* application must deal with any cleanup that should happen even
|
||||||
|
* for error exit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
METHODDEF(void) term_destination(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
DstPtr dst = (DstPtr)cinfo->dest;
|
||||||
|
|
||||||
|
// make sure any data left in the buffer is written out
|
||||||
|
const size_t bytes_in_buf = OUTPUT_BUF_SIZE - dst->pub.free_in_buffer;
|
||||||
|
if(vfs_io(dst->hf, bytes_in_buf, (void**)&dst->buf) != bytes_in_buf)
|
||||||
|
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||||
|
|
||||||
|
// flush file, if necessary.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare for output to a stdio stream.
|
||||||
|
* The caller must have already opened the stream, and is responsible
|
||||||
|
* for closing it after finishing compression.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GLOBAL(void) jpeg_vfs_dst(j_compress_ptr cinfo, Handle hf)
|
||||||
|
{
|
||||||
|
/* The destination object is made permanent so that multiple JPEG images
|
||||||
|
* can be written to the same file without re-executing jpeg_stdio_dest.
|
||||||
|
* This makes it dangerous to use this manager and a different destination
|
||||||
|
* manager serially with the same JPEG object, because their private object
|
||||||
|
* sizes may be different. Caveat programmer.
|
||||||
|
*/
|
||||||
|
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||||
|
cinfo->dest = (struct jpeg_destination_mgr*)(*cinfo->mem->alloc_small)
|
||||||
|
((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(VfsDstMgr));
|
||||||
|
}
|
||||||
|
|
||||||
|
DstPtr dst = (DstPtr)cinfo->dest;
|
||||||
|
dst->pub.init_destination = init_destination;
|
||||||
|
dst->pub.empty_output_buffer = empty_output_buffer;
|
||||||
|
dst->pub.term_destination = term_destination;
|
||||||
|
dst->hf = hf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user