aboutsummaryrefslogtreecommitdiff
path: root/Src/jpeg/amg.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/jpeg/amg.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/jpeg/amg.cpp')
-rw-r--r--Src/jpeg/amg.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/Src/jpeg/amg.cpp b/Src/jpeg/amg.cpp
new file mode 100644
index 00000000..cca284ca
--- /dev/null
+++ b/Src/jpeg/amg.cpp
@@ -0,0 +1,121 @@
+#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 \ No newline at end of file