mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
121 lines
3.1 KiB
C++
121 lines
3.1 KiB
C++
|
#include "amg.h"
|
||
|
#include "api__jpeg.h"
|
||
|
#include <setjmp.h>
|
||
|
extern "C"
|
||
|
{
|
||
|
#undef FAR
|
||
|
#include "jpeglib.h"
|
||
|
// our reader...
|
||
|
|
||
|
static void init_source( j_decompress_ptr cinfo )
|
||
|
{}
|
||
|
static const JOCTET jpeg_eof[] = { (JOCTET)0xFF, (JOCTET)JPEG_EOI };
|
||
|
static boolean fill_input_buffer( j_decompress_ptr cinfo )
|
||
|
{
|
||
|
cinfo->src->next_input_byte = jpeg_eof;
|
||
|
cinfo->src->bytes_in_buffer = 2;
|
||
|
return TRUE;
|
||
|
}
|
||
|
static void skip_input_data( j_decompress_ptr cinfo, long num_bytes )
|
||
|
{
|
||
|
//my_src_ptr src = (my_src_ptr) cinfo->src;
|
||
|
if ( num_bytes > 0 )
|
||
|
{
|
||
|
if ( num_bytes > (long)cinfo->src->bytes_in_buffer )
|
||
|
{
|
||
|
fill_input_buffer( cinfo );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cinfo->src->next_input_byte += (size_t)num_bytes;
|
||
|
cinfo->src->bytes_in_buffer -= (size_t)num_bytes;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
static void term_source( j_decompress_ptr cinfo )
|
||
|
{}
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
jpeg_destination_mgr pub;
|
||
|
uint8_t *buf;
|
||
|
int len;
|
||
|
} my_destination_mgr;
|
||
|
|
||
|
void init_destination( j_compress_ptr cinfo );
|
||
|
boolean empty_output_buffer( j_compress_ptr cinfo );
|
||
|
void term_destination( j_compress_ptr cinfo );
|
||
|
static void wasabi_jpgload_error_exit( j_common_ptr cinfo )
|
||
|
{
|
||
|
jmp_buf *stack_env = (jmp_buf *)cinfo->client_data;
|
||
|
longjmp( *stack_env, 1 );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
int AMGSucks::WriteAlbumArt(const void *data, size_t data_len, void **out, int *out_len)
|
||
|
{
|
||
|
*out = 0;
|
||
|
jmp_buf stack_env;
|
||
|
|
||
|
jpeg_decompress_struct cinfo_dec={0};
|
||
|
jpeg_compress_struct cinfo={0};
|
||
|
cinfo.client_data=&stack_env;
|
||
|
cinfo_dec.client_data=&stack_env;
|
||
|
|
||
|
if (setjmp(stack_env))
|
||
|
{
|
||
|
// longjmp will goto here
|
||
|
jpeg_destroy_decompress(&cinfo_dec);
|
||
|
jpeg_destroy_compress(&cinfo);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
jpeg_error_mgr jerr;
|
||
|
jpeg_source_mgr src = {(const JOCTET *)data,data_len,init_source,fill_input_buffer,skip_input_data,jpeg_resync_to_restart,term_source};
|
||
|
cinfo_dec.err = jpeg_std_error(&jerr);
|
||
|
jpeg_create_decompress(&cinfo_dec);
|
||
|
cinfo_dec.err->error_exit = wasabi_jpgload_error_exit;
|
||
|
cinfo_dec.src = &src;
|
||
|
|
||
|
if (jpeg_read_header(&cinfo_dec, TRUE) == JPEG_HEADER_OK)
|
||
|
{
|
||
|
cinfo.err = cinfo_dec.err;
|
||
|
jpeg_create_compress(&cinfo);
|
||
|
cinfo.err->error_exit = wasabi_jpgload_error_exit;
|
||
|
|
||
|
my_destination_mgr dest = {{0,65536,init_destination,empty_output_buffer,term_destination},0,65536};
|
||
|
dest.buf = (uint8_t *)WASABI_API_MEMMGR->sysMalloc(65536);
|
||
|
dest.pub.next_output_byte = dest.buf;
|
||
|
cinfo.dest = (jpeg_destination_mgr*)&dest;
|
||
|
cinfo.image_width = cinfo_dec.image_width;
|
||
|
cinfo.image_height = cinfo_dec.image_height;
|
||
|
cinfo.input_components = 4;
|
||
|
cinfo.in_color_space = JCS_RGB;
|
||
|
|
||
|
jpeg_copy_critical_parameters(&cinfo_dec, &cinfo);
|
||
|
jvirt_barray_ptr *stuff = jpeg_read_coefficients(&cinfo_dec);
|
||
|
jpeg_write_coefficients(&cinfo, stuff);
|
||
|
const char *blah = "AMG/AOL";
|
||
|
jpeg_write_marker(&cinfo, JPEG_COM, (JOCTET *)blah, (unsigned int)strlen(blah));
|
||
|
|
||
|
jpeg_finish_compress(&cinfo);
|
||
|
|
||
|
*out = dest.buf;
|
||
|
*out_len = dest.len - (int)dest.pub.free_in_buffer;
|
||
|
|
||
|
jpeg_destroy_decompress(&cinfo_dec);
|
||
|
jpeg_destroy_compress(&cinfo);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
#define CBCLASS AMGSucks
|
||
|
START_DISPATCH;
|
||
|
CB(WRITEALBUMART, WriteAlbumArt);
|
||
|
END_DISPATCH;
|
||
|
#undef CBCLASS
|