Page 1 of 1

Libjpg improvement

Posted: Tue Jul 11, 2006 7:18 am
by Polo35
Hey. ;)

Are you interested by a libjpg improvement.

I worked on a jpg viewer for ULE, and saw lot of jpg were not supported.
So i decided to take a look at libjpg.
And made some changes and wrote a new fonction call "jpgData *jpgOpenFILE(FILE *in_file, int mode)".

That work like "jpgData *jpgOpenRAW(u8 *data, int mode)" fonction, but need a FILE pointer for decompression.
You just need to open the file with fopen in your main prog and call the new fonction.

That solve all unsupported jpg problem.

Best regards

Polo

Posted: Thu Jul 27, 2006 7:32 am
by Polo35
So, nobody interested by a BIG libjpg improvement???

I'm surprised. ;)

Best regards

Polo

Posted: Thu Jul 27, 2006 9:24 am
by Oobles
I'm sure people are.. You can either post the changes as a diff file to the forums here, or send me an email and I'll see if I can find someone to import the changes.

regards,
David. aka Oobles.

Posted: Fri Jul 28, 2006 7:28 am
by Polo35
There is 3 diff for Makefile, libjpg.c, and libjpg.h.

Makefile:

Code: Select all

diff -ur libjpg/Makefile libjpg1/Makefile
--- libjpg/Makefile     2006-07-27 23:26:03.187500000 +0200
+++ libjpg1/Makefile    2006-07-14 10:58:36.890625000 +0200
@@ -7,7 +7,7 @@
         jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
         jfdctint.o
 # decompression library object files
-DLIBOBJECTS= jdapimin.o jdapistd.o jdatasrc.o jdtrans.o jdmaster.o \
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdmaster.o \
         jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
         jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
         jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
@@ -15,7 +15,7 @@
 LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
 
 EE_INCS = -I$(LIBJPG)/include -I.
-EE_LIB = libjpg.a
+EE_LIB = lib/libjpg.a
 EE_OBJS = libjpg.o $(LIBOBJECTS)
libjpg.c:

Code: Select all

diff -ur libjpg1/libjpg.c libjpg/libjpg.c
--- libjpg1/libjpg.c    2006-07-14 10:58:36.406250000 +0200
+++ libjpg/libjpg.c     2006-07-27 16:16:31.562500000 +0200
@@ -1,414 +1,630 @@
+/*
+# PS2 JPEG Library Port
+# Written by linuzappz.
+# Modified by ntba2 for myPS2.
+# Added jpgOpenFILE by Polo for ULE
+*/
+
 #include <tamtypes.h>
 #include <kernel.h>
 #include <string.h>
 #include <malloc.h>
-#include <fileio.h>
 #include <stdio.h>
-#include <screenshot.h>
+#include <screenshot.h>
+#include <fileXio_rpc.h>
 
 #include <libjpg.h>
-#include "jpeglib.h"
-
-typedef struct &#123;
-  struct jpeg_destination_mgr pub; /* public fields */
-
-  u8 *dest;
-  int size;
-
-  u8 *buffer;
+#include "jpeglib.h"
+#include "jerror.h"
+#include "setjmp.h"
+
+typedef struct &#123;
+       struct jpeg_error_mgr pub;      /* "public" fields */
+
+       jmp_buf setjmp_buffer;  /* for return to caller */
+&#125; custom_error_mgr;
+
+typedef struct &#123;
+       struct jpeg_destination_mgr pub; /* public fields */
+
+       u8 *dest;
+       int size;
+
+       u8 *buffer;
 &#125; _destination_mgr;
 
-typedef struct &#123;
-  /* libjpg private fields */
-  struct jpeg_decompress_struct dinfo;
-  struct jpeg_compress_struct cinfo;
-  struct jpeg_error_mgr jerr;
-
-  struct jpeg_source_mgr jsrc;
-  _destination_mgr jdst;
-
-  JSAMPLE *buffer;
-  u8 *data;
-  u8 *dest;
+typedef struct &#123;
+       /* libjpg private fields */
+       struct jpeg_decompress_struct dinfo;
+       struct jpeg_compress_struct cinfo;
+
+       custom_error_mgr jerr;
+
+       struct jpeg_source_mgr *jsrc;
+       _destination_mgr *jdst;
+
+       JSAMPLE *buffer;
+       u8 *data;
+       u8 *dest;
 &#125; jpgPrivate;
 
-int dLog=0;
-
-void __Log&#40;char *fmt, ...&#41; &#123;
-       char buf&#91;1024&#93;;
-       va_list list;
-
-/*     if &#40;dLog == 0&#41; &#123;
-               dLog = fioOpen&#40;"host&#58;dLog.txt", O_CREAT | O_WRONLY&#41;;
-       &#125;
-*/
-       va_start&#40;list, fmt&#41;;
-       vsprintf&#40;buf, fmt, list&#41;;
-       va_end&#40;list&#41;;
-       printf&#40;"%s", buf&#41;;
-//     fioWrite&#40;dLog, buf, strlen&#40;buf&#41;&#41;;
-
-//     fioClose&#40;dLog&#41;;
-&#125;
-
-
-void _src_init_source&#40;j_decompress_ptr cinfo&#41; &#123;
+void _src_init_source&#40; j_decompress_ptr cinfo &#41;
+&#123;
 &#125;
 
-boolean _src_fill_input_buffer&#40;j_decompress_ptr cinfo&#41; &#123;
-  return TRUE;
+boolean _src_fill_input_buffer&#40; j_decompress_ptr cinfo &#41;
+&#123;
+       return TRUE;
 &#125;
 
-void _src_skip_input_data&#40;j_decompress_ptr cinfo, long num_bytes&#41; &#123;
+void _src_skip_input_data&#40; j_decompress_ptr cinfo, long num_bytes &#41;
+&#123;
 &#125;
 
-boolean _src_resync_to_restart&#40;j_decompress_ptr cinfo, int desired&#41; &#123;
-  return TRUE;
+boolean _src_resync_to_restart&#40; j_decompress_ptr cinfo, int desired &#41;
+&#123;
+       return TRUE;
 &#125;
 
-void _src_term_source&#40;j_decompress_ptr cinfo&#41; &#123;
+void _src_term_source&#40; j_decompress_ptr cinfo &#41;
+&#123;
 &#125;
-
-void _src_output_message&#40;j_common_ptr cinfo&#41; &#123;
-  char buffer&#91;JMSG_LENGTH_MAX&#93;;
-
-  /* Create the message */
-  &#40;*cinfo->err->format_message&#41; &#40;cinfo, buffer&#41;;
-
-#ifdef DEBUG
-  printf&#40;"%s\n", buffer&#41;;
-#endif
+
+//
+// jpg_error_exit - this replaces the standard error_exit function
+//
+
+void custom_error_exit&#40; j_common_ptr cinfo &#41;
+&#123;
+       custom_error_mgr *cerr = &#40;custom_error_mgr*&#41; cinfo->err;
+
+       /* Always display the message */
+       &#40;*cinfo->err->output_message&#41; &#40;cinfo&#41;;
+
+       /* Let the memory manager delete any temp files before we die */
+       jpeg_destroy&#40;cinfo&#41;;
+
+       // perform a long jump to previously saved environment
+       longjmp&#40; cerr->setjmp_buffer, 1 &#41;;
+&#125;
+
+
+//
+// custom_emit_message - this replaces the standard emit_message function
+//
+
+void custom_emit_message&#40; j_common_ptr cinfo, int msg_level &#41;
+&#123;
+       struct jpeg_error_mgr *err = cinfo->err;
+
+       // this message is harmless, we will just ignore it
+       if&#40; cinfo->err->msg_code == JWRN_EXTRANEOUS_DATA &#41;
+               return;
+
+       if&#40; msg_level < 0 &#41;
+       &#123;
+               /* It's a warning message.  Since corrupt files may generate many warnings,
+                * the policy implemented here is to show only the first warning,
+                * unless trace_level >= 3.
+                */
+               if&#40; err->num_warnings == 0 || err->trace_level >= 3 &#41;
+                       &#40;*err->output_message&#41; &#40;cinfo&#41;;
+
+               /* Always count warnings in num_warnings. */
+               err->num_warnings++;
+       &#125; else &#123;
+               /* It's a trace message.  Show it if trace_level >= msg_level. */
+               if&#40; err->trace_level >= msg_level &#41;
+                       &#40;*err->output_message&#41; &#40;cinfo&#41;;
+       &#125;
+&#125;
+
+jpgData *jpgOpenRAW&#40; u8 *data, int size, int mode &#41;
+&#123;
+       struct jpeg_decompress_struct *dinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc&#40; sizeof&#40;jpgData&#41; &#41;;
+       if&#40; jpg == NULL &#41;
+               return NULL;
+
+       memset&#40; jpg, 0, sizeof&#40;jpgData&#41; &#41;;
+
+       priv = malloc&#40; sizeof&#40;jpgPrivate&#41; &#41;;
+       if&#40; priv == NULL &#41;
+               return NULL;
+
+       jpg->priv       = priv;
+       dinfo           = &priv->dinfo;
+  
+       /* Initialize the JPEG decompression object with default error handling. */
+       dinfo->err      = jpeg_std_error&#40;&priv->jerr.pub&#41;;
+
+       // install custom handlers
+       dinfo->err->emit_message        = custom_emit_message;
+       dinfo->err->error_exit          = custom_error_exit;
+
+       // execution will jump here if an error occurs while processing an jpg
+       if&#40; setjmp&#40;priv->jerr.setjmp_buffer&#41; &#41; &#123;
+               jpgClose&#40;jpg&#41;;
+               return NULL;
+       &#125;
+
+       jpeg_create_decompress&#40;dinfo&#41;;
+
+       /* Specify data source for decompression */
+       priv->jsrc->next_input_byte   = data;
+       priv->jsrc->bytes_in_buffer   = size;
+       priv->jsrc->init_source       = _src_init_source;
+       priv->jsrc->fill_input_buffer = _src_fill_input_buffer;
+       priv->jsrc->skip_input_data   = _src_skip_input_data;
+       priv->jsrc->resync_to_restart = _src_resync_to_restart;
+       priv->jsrc->term_source       = _src_term_source;
+       dinfo->src = priv->jsrc;
+
+       /* Read file header, set default decompression parameters */
+       jpeg_read_header&#40;dinfo, TRUE&#41;;
+
+       /* Calculate output image dimensions so we can allocate space */
+       jpeg_calc_output_dimensions&#40;dinfo&#41;;
+
+       priv->buffer = &#40;*dinfo->mem->alloc_small&#41; 
+               &#40;&#40;j_common_ptr&#41; dinfo, JPOOL_IMAGE, dinfo->output_width * dinfo->out_color_components&#41;;
+
+       /* Start decompressor */
+       jpeg_start_decompress&#40;dinfo&#41;;
+
+       // ntba2
+       if&#40; &#40;mode == JPG_WIDTH_FIX&#41; && &#40;dinfo->output_width % 4&#41; &#41;
+               jpg->width = dinfo->output_width - &#40;dinfo->output_width % 4&#41;;
+       else
+               jpg->width  = dinfo->output_width;
+
+       jpg->height = dinfo->output_height;
+       jpg->bpp    = dinfo->out_color_components * 8;
+
+       /* All done. */
+       return&#40; priv->jerr.pub.num_warnings ? NULL &#58; jpg &#41;;
+&#125;
+
+jpgData *jpgOpen&#40; char *filename, int mode &#41;
+&#123;
+       jpgData *jpg;
+       jpgPrivate *priv;
+       u8 *data;
+       int size;
+       int fd;
+
+       fd = fileXioOpen&#40; filename, O_RDONLY, 0 &#41;;
+       if&#40; fd == -1 &#41; &#123;
+               printf&#40;"jpgOpen&#58; error opening '%s'\n", filename&#41;;
+               return NULL;
+       &#125;
+
+       size = fileXioLseek&#40; fd, 0, SEEK_END &#41;;
+       fileXioLseek&#40; fd, 0, SEEK_SET &#41;;
+
+       data = &#40;u8*&#41;malloc&#40;size&#41;;
+       if&#40; data == NULL &#41;
+               return NULL;
+
+       fileXioRead&#40; fd, data, size &#41;;
+       fileXioClose&#40;fd&#41;;
+
+       jpg = jpgOpenRAW&#40; data, size, mode &#41;;
+       if&#40; jpg == NULL &#41;
+               return NULL;
+
+       priv = jpg->priv;
+       priv->data = data;
+
+       return jpg;
+&#125;
+
+int jpgReadImage&#40; jpgData *jpg, u8 *dest &#41;
+&#123;
+       JDIMENSION num_scanlines;
+       jpgPrivate *priv = jpg->priv;
+       int width;
+
+       width = jpg->width * priv->dinfo.out_color_components;
+
+       // execution will jump here if an error occurs while processing an jpg
+       if&#40; setjmp&#40;priv->jerr.setjmp_buffer&#41; &#41; &#123;
+               jpgClose&#40;jpg&#41;;
+               return -1;
+       &#125;
+
+       /* Process data */
+       while&#40; priv->dinfo.output_scanline < priv->dinfo.output_height &#41;
+       &#123;
+               num_scanlines = jpeg_read_scanlines&#40;&priv->dinfo, &priv->buffer, 1&#41;;
+
+               if&#40; num_scanlines != 1 &#41;
+                       break;
+
+               // ntba2
+               memcpy&#40; dest, priv->buffer, jpg->width * priv->dinfo.out_color_components &#41;;
+               dest += width;
+       &#125;
+
+       /* Finish decompression and release memory.
+        * I must do it in this order because output module has allocated memory
+        * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
+        */
+
+       jpeg_finish_decompress&#40;&priv->dinfo&#41;;
+       jpeg_destroy_decompress&#40;&priv->dinfo&#41;;
+
+       return&#40; priv->jerr.pub.num_warnings ? -1 &#58; 0 &#41;;
 &#125;
 
-void _src_error_exit&#40;j_common_ptr cinfo&#41; &#123;
-  /* Always display the message */
-  &#40;*cinfo->err->output_message&#41; &#40;cinfo&#41;;
-
-  /* Let the memory manager delete any temp files before we die */
-  jpeg_destroy&#40;cinfo&#41;;
+#define OUTPUT_BUF_SIZE        &#40;64*1024&#41;
 
-//  exit&#40;EXIT_FAILURE&#41;;
+void _dest_init_destination&#40; j_compress_ptr cinfo &#41;
+&#123;
 &#125;
 
+boolean _dest_empty_output_buffer&#40; j_compress_ptr cinfo &#41;
+&#123;
+
+       _destination_mgr *dest = &#40;_destination_mgr*&#41; cinfo->dest;
+
+       dest->dest = realloc&#40;dest->dest, dest->size+OUTPUT_BUF_SIZE&#41;;
+       memcpy&#40;dest->dest+dest->size, dest->buffer, OUTPUT_BUF_SIZE&#41;;
+
+       cinfo->dest->next_output_byte = dest->buffer;
+       cinfo->dest->free_in_buffer   = OUTPUT_BUF_SIZE;
+
+       dest->size+= OUTPUT_BUF_SIZE;
+
+       return TRUE;
+&#125;
+
+void _dest_term_destination&#40; j_compress_ptr cinfo &#41;
+&#123;
+       _destination_mgr *dest = &#40;_destination_mgr*&#41; cinfo->dest;
+       int size = OUTPUT_BUF_SIZE - cinfo->dest->free_in_buffer;
+
+       dest->dest = realloc&#40;dest->dest, dest->size+size&#41;;
+       memcpy&#40;dest->dest+dest->size, dest->buffer, size&#41;;
+
+       dest->size+= size;
+&#125;
+
+jpgData *jpgCreateRAW&#40; u8 *data, int width, int height, int bpp &#41;
+&#123;
+       struct jpeg_compress_struct *cinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc&#40;sizeof&#40;jpgData&#41;&#41;;
+       if&#40; jpg == NULL &#41;
+               return NULL;
+
+       memset&#40;jpg, 0, sizeof&#40;jpgData&#41;&#41;;
+       priv = malloc&#40;sizeof&#40;jpgPrivate&#41;&#41;;
+       if&#40; priv == NULL &#41;
+               return NULL;
+
+       jpg->priv = priv;
+       cinfo = &priv->cinfo;
+
+       /* Initialize the JPEG compression object with default error handling. */
+       cinfo->err = jpeg_std_error&#40;&priv->jerr.pub&#41;;
+       jpeg_create_compress&#40;cinfo&#41;;
+
+       priv->data = data;
+       priv->buffer = malloc&#40;OUTPUT_BUF_SIZE&#41;;
+       if&#40; priv->buffer == NULL &#41;
+               return NULL;
+
+       priv->jdst->pub.next_output_byte                = priv->buffer;
+       priv->jdst->pub.free_in_buffer          = OUTPUT_BUF_SIZE;
+       priv->jdst->pub.init_destination                = _dest_init_destination;
+       priv->jdst->pub.empty_output_buffer     = _dest_empty_output_buffer;
+       priv->jdst->pub.term_destination                = _dest_term_destination;
+       priv->jdst->buffer                                      = priv->buffer;
+
+       /* Specify data source for decompression */
+       cinfo->dest = &#40;struct jpeg_destination_mgr *&#41;&priv->jdst;
+
+       cinfo->image_width      = width;                                        /* image width and height, in pixels */
+       cinfo->image_height = height;
+
+       if&#40; bpp == 8 &#41; &#123;
+               cinfo->input_components = 1;                            /* # of color components per pixel */
+               cinfo->in_color_space   = JCS_GRAYSCALE;        /* colorspace of input image */
+       &#125;
+       else &#123;
+               cinfo->input_components = 3;                            /* # of color components per pixel */
+               cinfo->in_color_space   = JCS_RGB;                      /* colorspace of input image */
+       &#125;
+
+       jpeg_set_defaults&#40;cinfo&#41;;
+
+       jpeg_set_quality&#40; cinfo, 100, TRUE &#41;;
+       jpeg_start_compress&#40;cinfo, TRUE&#41;;
+
+       jpg->width      = cinfo->image_width;
+       jpg->height = cinfo->image_height;
+       jpg->bpp        = cinfo->input_components*8;
+
+       /* All done. */
+       return&#40; priv->jerr.pub.num_warnings ? NULL &#58; jpg &#41;;
+&#125;
+
+int jpgCompressImageRAW&#40; jpgData *jpg, u8 **dest &#41;
+&#123;
+       jpgPrivate *priv = jpg->priv;
+       _destination_mgr *_dest = &#40;_destination_mgr*&#41; priv->cinfo.dest;
+       int width = priv->cinfo.image_width * priv->cinfo.input_components;
+       JSAMPROW row_pointer&#91;1&#93;;        /* pointer to a single row */
+
+       _dest->dest = NULL;
+       _dest->size = 0;
+
+       while&#40; priv->cinfo.next_scanline < priv->cinfo.image_height &#41;
+       &#123;
+               row_pointer&#91;0&#93; = & priv->data&#91;priv->cinfo.next_scanline * width&#93;;
+               jpeg_write_scanlines&#40;&priv->cinfo, row_pointer, 1&#41;;
+       &#125;
+
+       jpeg_finish_compress&#40;&priv->cinfo&#41;;
+       *dest = _dest->dest;
+
+       return&#40; priv->jerr.pub.num_warnings ? -1 &#58; _dest->size &#41;;
+&#125;
+
+void jpgClose&#40; jpgData *jpg &#41;
+&#123;
+       jpgPrivate *priv = jpg->priv;
+
+       if&#40; priv->data &#41;
+               free&#40;priv->data&#41;;
+
+       free&#40;priv&#41;;
+       free&#40;jpg&#41;;
+&#125;
+
+#define PS2SS_GSPSMCT32                0
+#define PS2SS_GSPSMCT24                1
+#define PS2SS_GSPSMCT16                2
+
+int jpgScreenshot&#40; const char* pFilename,unsigned int VramAdress, unsigned int Width, unsigned int Height, unsigned int Psm &#41;
+&#123;
+       s32 file_handle;
+       u32 y;
+       static u32 in_buffer&#91;1024*4&#93;;  // max 1024*32bit for a line, should be ok
+       u8 *out_buffer;
+       u8 *p_out;
+       jpgData *jpg;
+       u8 *data;
+       int ret;
+
+       file_handle = fileXioOpen&#40; pFilename, O_CREAT | O_WRONLY, 0 &#41;;
+
+       // make sure we could open the file for output
+       if&#40; file_handle < 0 &#41;
+               return 0;
+
+       out_buffer = malloc&#40; Width * Height * 3 &#41;;
+       if&#40; out_buffer == NULL &#41;
+               return 0;
+
+       p_out = out_buffer;
+
+       // Check if we have a tempbuffer, if we do we use it 
+       for&#40; y = 0; y < Height; y++ &#41;
+       &#123;
+               ps2_screenshot&#40; in_buffer, VramAdress, 0, y, Width, 1, Psm &#41;;
+
+               if&#40; Psm == PS2SS_GSPSMCT16 &#41;
+               &#123;
+                       u32 x;
+                       u16* p_in  = &#40;u16*&#41;&in_buffer;
+        
+                       for&#40; x = 0; x < Width; x++ &#41;
+                       &#123;
+                               u32 r = &#40;p_in&#91;x&#93; & 31&#41; << 3;
+                               u32 g = &#40;&#40;p_in&#91;x&#93; >> 5&#41; & 31&#41; << 3;
+                               u32 b = &#40;&#40;p_in&#91;x&#93; >> 10&#41; & 31&#41; << 3;
+
+                               p_out&#91;x*3+0&#93; = r;
+                               p_out&#91;x*3+1&#93; = g;
+                               p_out&#91;x*3+2&#93; = b;
+                       &#125;
+               &#125;
+               else
+                       if&#40; Psm == PS2SS_GSPSMCT24 &#41;
+                       &#123;
+                               u32 x;
+                               u8* p_in  = &#40;u8*&#41;&in_buffer;
+
+                               for&#40; x = 0; x < Width; x++ &#41;
+                               &#123;
+                                       u8 r =  *p_in++;
+                                       u8 g =  *p_in++;
+                                       u8 b =  *p_in++;
+
+                                       p_out&#91;x*3+0&#93; = r;
+                                       p_out&#91;x*3+1&#93; = g;
+                                       p_out&#91;x*3+2&#93; = b;
+                               &#125;
+                       &#125;
+                       else
+                       &#123;
+                               u8 *p_in = &#40;u8 *&#41; &in_buffer;
+                               u32 x;
+
+                               for&#40;x = 0; x < Width; x++&#41;
+                               &#123;
+                                       u8 r = *p_in++;
+                                       u8 g = *p_in++;
+                                       u8 b = *p_in++;
+
+                                       *p_in++;
+
+                                       p_out&#91;x*3+0&#93; = r;
+                                       p_out&#91;x*3+1&#93; = g;
+                                       p_out&#91;x*3+2&#93; = b;
+                               &#125;
+                       &#125;
+
+                       p_out+= Width*3;
+       &#125;
+
+       jpg = jpgCreateRAW&#40;out_buffer, Width, Height, 24&#41;;
+       ret = jpgCompressImageRAW&#40;jpg, &data&#41;;
+
+       fileXioWrite&#40; file_handle, data, ret &#41;;
+       jpgClose&#40;jpg&#41;;
+
+       fileXioClose&#40; file_handle &#41;;
+       free&#40;out_buffer&#41;;
+
+       return 0;
+&#125;
+
+/*
+ * Marker processor for COM and interesting APPn markers.
+ * This replaces the library's built-in processor, which just skips the marker.
+ * We want to print out the marker as text, to the extent possible.
+ * Note this code relies on a non-suspending data source.
+ */
+
+LOCAL&#40;unsigned int&#41;
+jpeg_getc &#40;j_decompress_ptr dinfo&#41;
+/* Read next byte */
+&#123;
+  struct jpeg_source_mgr * datasrc = dinfo->src;
 
-jpgData *jpgOpenRAW&#40;u8 *data, int size&#41; &#123;
-  struct jpeg_decompress_struct *dinfo;
-  jpgPrivate *priv;
-  jpgData *jpg;
-
-  jpg = malloc&#40;sizeof&#40;jpgData&#41;&#41;;
-  if &#40;jpg == NULL&#41; return NULL;
-
-  memset&#40;jpg, 0, sizeof&#40;jpgData&#41;&#41;;
-  priv = malloc&#40;sizeof&#40;jpgPrivate&#41;&#41;;
-  if &#40;priv == NULL&#41; return NULL;
-
-  jpg->priv = priv;
-  dinfo = &priv->dinfo;
-  /* Initialize the JPEG decompression object with default error handling. */
-  dinfo->err = jpeg_std_error&#40;&priv->jerr&#41;;
-  jpeg_create_decompress&#40;dinfo&#41;;
-
-  /* Specify data source for decompression */
-  priv->jsrc.next_input_byte   = data;
-  priv->jsrc.bytes_in_buffer   = size;
-  priv->jsrc.init_source       = _src_init_source;
-  priv->jsrc.fill_input_buffer = _src_fill_input_buffer;
-  priv->jsrc.skip_input_data   = _src_skip_input_data;
-  priv->jsrc.resync_to_restart = _src_resync_to_restart;
-  priv->jsrc.term_source       = _src_term_source;
-  dinfo->src = &priv->jsrc;
-
-  /* Read file header, set default decompression parameters */
-  jpeg_read_header&#40;dinfo, TRUE&#41;;
-
-  /* Calculate output image dimensions so we can allocate space */
-  jpeg_calc_output_dimensions&#40;dinfo&#41;;
-
-  priv->buffer = &#40;*dinfo->mem->alloc_small&#41;
-      &#40;&#40;j_common_ptr&#41; dinfo, JPOOL_IMAGE,
-       dinfo->output_width * dinfo->out_color_components&#41;;
-
-  /* Start decompressor */
-  jpeg_start_decompress&#40;dinfo&#41;;
-
-  jpg->width  = dinfo->output_width;
-  jpg->height = dinfo->output_height;
-  jpg->bpp    = dinfo->out_color_components*8;
-
-  /* All done. */
-  return&#40;priv->jerr.num_warnings ? NULL &#58; jpg&#41;;
-&#125;
-
-jpgData *jpgOpen&#40;char *filename&#41; &#123;
-  jpgData *jpg;
-  jpgPrivate *priv;
-  u8 *data;
-  int size;
-  int fd;
-
-  fd = fioOpen&#40;filename, O_RDONLY&#41;;
-  if &#40;fd == -1&#41; &#123;
-    printf&#40;"jpgOpen&#58; error opening '%s'\n", filename&#41;;
-    return NULL;
-  &#125;
-  size = fioLseek&#40;fd, 0, SEEK_END&#41;;
-  fioLseek&#40;fd, 0, SEEK_SET&#41;;
-  data = &#40;u8*&#41;malloc&#40;size&#41;;
-  if &#40;data == NULL&#41; return NULL;
-  fioRead&#40;fd, data, size&#41;;
-  fioClose&#40;fd&#41;;
-
-  jpg = jpgOpenRAW&#40;data, size&#41;;
-  if &#40;jpg == NULL&#41; return NULL;
-  priv = jpg->priv;
-  priv->data = data;
-
-  return jpg;
-&#125;
-
-int  jpgReadImage&#40;jpgData *jpg, u8 *dest&#41; &#123;
-  JDIMENSION num_scanlines;
-  jpgPrivate *priv = jpg->priv;
-  int width = priv->dinfo.output_width * priv->dinfo.out_color_components;
-
-  /* Process data */
-  while &#40;priv->dinfo.output_scanline < priv->dinfo.output_height&#41; &#123;
-    num_scanlines = jpeg_read_scanlines&#40;&priv->dinfo, &priv->buffer, 1&#41;;
-       if &#40;num_scanlines != 1&#41; break;
-       memcpy&#40;dest, priv->buffer, priv->dinfo.output_width * priv->dinfo.out_color_components&#41;;
-       dest+= width;
+  if &#40;datasrc->bytes_in_buffer == 0&#41; &#123;
+    if &#40;! &#40;*datasrc->fill_input_buffer&#41; &#40;dinfo&#41;&#41;
+      ERREXIT&#40;dinfo, JERR_CANT_SUSPEND&#41;;
   &#125;
-
-  /* Finish decompression and release memory.
-   * I must do it in this order because output module has allocated memory
-   * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
-   */
-  jpeg_finish_decompress&#40;&priv->dinfo&#41;;
-  jpeg_destroy_decompress&#40;&priv->dinfo&#41;;
-
-  return&#40;priv->jerr.num_warnings ? -1 &#58; 0&#41;;
+  datasrc->bytes_in_buffer--;
+  return GETJOCTET&#40;*datasrc->next_input_byte++&#41;;
 &#125;
 
-#define OUTPUT_BUF_SIZE        &#40;64*1024&#41;
-
-void _dest_init_destination&#40;j_compress_ptr cinfo&#41; &#123;
-//__Log&#40;"_dest_init_destination\n"&#41;;
-&#125;
-
-boolean _dest_empty_output_buffer&#40;j_compress_ptr cinfo&#41; &#123;
-  _destination_mgr *dest = &#40;_destination_mgr*&#41; cinfo->dest;
-
-//__Log&#40;"_dest_empty_output_buffer, %d\n", dest->size&#41;;
-  dest->dest = realloc&#40;dest->dest, dest->size+OUTPUT_BUF_SIZE&#41;;
-  memcpy&#40;dest->dest+dest->size, dest->buffer, OUTPUT_BUF_SIZE&#41;;
+METHODDEF&#40;boolean&#41;
+print_text_marker &#40;j_decompress_ptr dinfo&#41;
+&#123;
+  boolean traceit = &#40;dinfo->err->trace_level >= 1&#41;;
+  INT32 length;
+  unsigned int ch;
+  unsigned int lastch = 0;
+
+  length = jpeg_getc&#40;dinfo&#41; << 8;
+  length += jpeg_getc&#40;dinfo&#41;;
+  length -= 2;                 /* discount the length word itself */
+
+  if &#40;traceit&#41; &#123;
+    if &#40;dinfo->unread_marker == JPEG_COM&#41;
+      fprintf&#40;stderr, "Comment, length %ld&#58;\n", &#40;long&#41; length&#41;;
+    else                       /* assume it is an APPn otherwise */
+      fprintf&#40;stderr, "APP%d, length %ld&#58;\n",
+             dinfo->unread_marker - JPEG_APP0, &#40;long&#41; length&#41;;
+  &#125;
 
-  cinfo->dest->next_output_byte = dest->buffer;
-  cinfo->dest->free_in_buffer   = OUTPUT_BUF_SIZE;
+  while &#40;--length >= 0&#41; &#123;
+    ch = jpeg_getc&#40;dinfo&#41;;
+    if &#40;traceit&#41; &#123;
+      /* Emit the character in a readable form.
+       * Nonprintables are converted to \nnn form,
+       * while \ is converted to \\.
+       * Newlines in CR, CR/LF, or LF form will be printed as one newline.
+       */
+      if &#40;ch == '\r'&#41; &#123;
+       fprintf&#40;stderr, "\n"&#41;;
+      &#125; else if &#40;ch == '\n'&#41; &#123;
+       if &#40;lastch != '\r'&#41;
+         fprintf&#40;stderr, "\n"&#41;;
+      &#125; else if &#40;ch == '\\'&#41; &#123;
+       fprintf&#40;stderr, "\\\\"&#41;;
+      &#125; else if &#40;isprint&#40;ch&#41;&#41; &#123;
+       putc&#40;ch, stderr&#41;;
+      &#125; else &#123;
+       fprintf&#40;stderr, "\\%03o", ch&#41;;
+      &#125;
+      lastch = ch;
+    &#125;
+  &#125;
 
-  dest->size+= OUTPUT_BUF_SIZE;
+  if &#40;traceit&#41;
+    fprintf&#40;stderr, "\n"&#41;;
 
   return TRUE;
 &#125;
 
-void _dest_term_destination&#40;j_compress_ptr cinfo&#41; &#123;
-  _destination_mgr *dest = &#40;_destination_mgr*&#41; cinfo->dest;
-  int size = OUTPUT_BUF_SIZE - cinfo->dest->free_in_buffer;
-
-//__Log&#40;"_dest_term_destination, %d\n", dest->size&#41;;
-  dest->dest = realloc&#40;dest->dest, dest->size+size&#41;;
-  memcpy&#40;dest->dest+dest->size, dest->buffer, size&#41;;
-
-  dest->size+= size;
-&#125;
-
-jpgData *jpgCreateRAW&#40;u8 *data, int width, int height, int bpp&#41; &#123;
-  struct jpeg_compress_struct *cinfo;
-  jpgPrivate *priv;
-  jpgData *jpg;
-
-//__Log&#40;"jpgCreateRAW\n"&#41;;
-  jpg = malloc&#40;sizeof&#40;jpgData&#41;&#41;;
-  if &#40;jpg == NULL&#41; return NULL;
-
-//__Log&#40;"jpgCreateRAW1\n"&#41;;
-  memset&#40;jpg, 0, sizeof&#40;jpgData&#41;&#41;;
-  priv = malloc&#40;sizeof&#40;jpgPrivate&#41;&#41;;
-  if &#40;priv == NULL&#41; return NULL;
-
-//__Log&#40;"jpgCreateRAW2\n"&#41;;
-  jpg->priv = priv;
-  cinfo = &priv->cinfo;
-
-  /* Initialize the JPEG compression object with default error handling. */
-  cinfo->err = jpeg_std_error&#40;&priv->jerr&#41;;
-  jpeg_create_compress&#40;cinfo&#41;;
-
-//__Log&#40;"jpgCreateRAW3\n"&#41;;
-  priv->data = data;
-  priv->buffer = malloc&#40;OUTPUT_BUF_SIZE&#41;;
-  if &#40;priv->buffer == NULL&#41; return NULL;
-//__Log&#40;"jpgCreateRAW3 %p\n", priv->buffer&#41;;
-
-  priv->jdst.pub.next_output_byte = priv->buffer;
-  priv->jdst.pub.free_in_buffer   = OUTPUT_BUF_SIZE;
-  priv->jdst.pub.init_destination = _dest_init_destination;
-  priv->jdst.pub.empty_output_buffer = _dest_empty_output_buffer;
-  priv->jdst.pub.term_destination = _dest_term_destination;
-  priv->jdst.buffer = priv->buffer;
+jpgData *jpgOpenFILE&#40; FILE *in_file, int mode &#41;
+&#123;
+       struct jpeg_decompress_struct *dinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc&#40; sizeof&#40;jpgData&#41; &#41;;
+       if&#40; jpg == NULL &#41;
+               return NULL;
+
+       memset&#40; jpg, 0, sizeof&#40;jpgData&#41; &#41;;
+
+       priv = malloc&#40; sizeof&#40;jpgPrivate&#41; &#41;;
+       if&#40; priv == NULL &#41;
+               return NULL;
+
+       jpg->priv       = priv;
+       dinfo           = &priv->dinfo;
+  
+  /* Install default error handling. */
+       dinfo->err      = jpeg_std_error&#40;&priv->jerr.pub&#41;;
+       dinfo->err->emit_message        = custom_emit_message;
+       dinfo->err->error_exit          = custom_error_exit;
+
+       /* Execution will jump here if an error occurs while processing an jpg */
+       if&#40; setjmp&#40;priv->jerr.setjmp_buffer&#41; &#41; &#123;
+               jpgClose&#40;jpg&#41;;
+               return NULL;
+       &#125;
+
+  /* Initialize the JPEG decompression. */
+       jpeg_create_decompress&#40;dinfo&#41;;
+
+  /* Insert custom marker processor for COM and APP12.
+   * APP12 is used by some digital camera makers for textual info,
+   * so we provide the ability to display it as text.
+   * If you like, additional APPn marker types can be selected for display,
+   * but don't try to override APP0 or APP14 this way &#40;see libjpeg.doc&#41;.
+   */
+  jpeg_set_marker_processor&#40;dinfo, JPEG_COM, print_text_marker&#41;;
+  jpeg_set_marker_processor&#40;dinfo, JPEG_APP0+12, print_text_marker&#41;;
 
-//printf&#40;"%p, %p\n", &priv->jdst.pub.next_output_byte, &priv->jdst&#41;;
   /* Specify data source for decompression */
-  cinfo->dest = &#40;struct jpeg_destination_mgr *&#41;&priv->jdst;
-
-//__Log&#40;"jpgCreateRAW4\n"&#41;;
-  cinfo->image_width = width;  /* image width and height, in pixels */
-  cinfo->image_height = height;
-  if &#40;bpp == 8&#41; &#123;
-    cinfo->input_components = 1;       /* # of color components per pixel */
-    cinfo->in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
-  &#125; else &#123;
-    cinfo->input_components = 3;       /* # of color components per pixel */
-    cinfo->in_color_space = JCS_RGB;    /* colorspace of input image */
-  &#125;
+  jpeg_stdio_src&#40;dinfo, in_file&#41;;
+       priv->jsrc = dinfo->src;
 
-//__Log&#40;"jpgCreateRAW5\n"&#41;;
-  jpeg_set_defaults&#40;cinfo&#41;;
-  jpeg_start_compress&#40;cinfo, TRUE&#41;;
-
-  jpg->width = cinfo->image_width;
-  jpg->height = cinfo->image_height;
-  jpg->bpp = cinfo->input_components*8;
-//__Log&#40;"jpgCreateRAW6\n"&#41;;
-
-  /* All done. */
-  return&#40;priv->jerr.num_warnings ? NULL &#58; jpg&#41;;
-&#125;
-
-int jpgCompressImageRAW&#40;jpgData *jpg, u8 **dest&#41; &#123;
-  jpgPrivate *priv = jpg->priv;
-  _destination_mgr *_dest = &#40;_destination_mgr*&#41; priv->cinfo.dest;
-  int width = priv->cinfo.image_width * priv->cinfo.input_components;
-  JSAMPROW row_pointer&#91;1&#93;;     /* pointer to a single row */
-
-  _dest->dest = NULL;
-  _dest->size = 0;
-
-//__Log&#40;"jpgCompressImageRAW\n"&#41;;
-  while &#40;priv->cinfo.next_scanline < priv->cinfo.image_height&#41; &#123;
-    row_pointer&#91;0&#93; = & priv->data&#91;priv->cinfo.next_scanline * width&#93;;
-//__Log&#40;"jpgCompressImageRAW %d %x &#40;%d&#41;\n", priv->cinfo.next_scanline, row_pointer&#91;0&#93;, priv->jdst.pub.free_in_buffer&#41;;
-    jpeg_write_scanlines&#40;&priv->cinfo, row_pointer, 1&#41;;
-  &#125;
-//__Log&#40;"jpgCompressImageRAW2\n"&#41;;
-  jpeg_finish_compress&#40;&priv->cinfo&#41;;
-  *dest = _dest->dest;
-
-  return&#40;priv->jerr.num_warnings ? -1 &#58; _dest->size&#41;;
-&#125;
-
-void jpgClose&#40;jpgData *jpg&#41; &#123;
-  jpgPrivate *priv = jpg->priv;
-  if &#40;priv->data&#41; free&#40;priv->data&#41;;
-  free&#40;priv&#41;;
-  free&#40;jpg&#41;;
-&#125;
-
-#define PS2SS_GSPSMCT32           0
-#define PS2SS_GSPSMCT24           1
-#define PS2SS_GSPSMCT16           2
-
-int jpgScreenshot&#40; const char* pFilename,unsigned int VramAdress,
-                         unsigned int Width, unsigned int Height, unsigned int Psm &#41;
-&#123;
-  s32 file_handle;
-  u32 y;
-  static u32 in_buffer&#91;1024*4&#93;;  // max 1024*32bit for a line, should be ok
-  u8 *out_buffer;
-  u8 *p_out;
-  jpgData *jpg;
-  u8 *data;
-  int ret;
-
-  file_handle = fioOpen&#40; pFilename, O_CREAT|O_WRONLY &#41;;
-
-  // make sure we could open the file for output
-
-  if&#40; file_handle < 0 &#41;
-    return 0;
-
-  out_buffer = malloc&#40; Width*Height*3 &#41;;
-  if&#40; out_buffer == NULL &#41;
-    return 0;
-  p_out = out_buffer;
-
-  /////////////////////////////////////////////////////////////////////////////
-  // Check if we have a tempbuffer, if we do we use it 
-
-  for&#40; y = 0; y < Height; y++ &#41;
-  &#123;
-    ps2_screenshot&#40; in_buffer, VramAdress, 0, y, Width, 1, Psm &#41;;
-
-    if&#40; Psm == PS2SS_GSPSMCT16 &#41;
-    &#123;
-      u32 x;
-      u16* p_in  = &#40;u16*&#41;&in_buffer;
-        
-      for&#40; x = 0; x < Width; x++ &#41;
-      &#123;
-        u32 r = &#40;p_in&#91;x&#93; & 31&#41; << 3;
-        u32 g = &#40;&#40;p_in&#91;x&#93; >> 5&#41; & 31&#41; << 3;
-        u32 b = &#40;&#40;p_in&#91;x&#93; >> 10&#41; & 31&#41; << 3;
-         p_out&#91;x*3+0&#93; = r;
-         p_out&#91;x*3+1&#93; = g;
-         p_out&#91;x*3+2&#93; = b;
-      &#125;
-    &#125;
-    else
-    if&#40; Psm == PS2SS_GSPSMCT24 &#41;
-    &#123;
-      u32 x;
-      u8* p_in  = &#40;u8*&#41;&in_buffer;
-        
-      for&#40; x = 0; x < Width; x++ &#41;
-      &#123;
-        u8 r =  *p_in++;
-        u8 g =  *p_in++;
-        u8 b =  *p_in++;
-        p_out&#91;x*3+0&#93; = r;
-        p_out&#91;x*3+1&#93; = g;
-        p_out&#91;x*3+2&#93; = b;
-      &#125;
-    &#125;
-    else
-    &#123;
-       u8 *p_in = &#40;u8 *&#41; &in_buffer;
-       u32 x;
-
-       for&#40;x = 0; x < Width; x++&#41;
-       &#123;
-         u8 r = *p_in++;
-         u8 g = *p_in++;
-         u8 b = *p_in++;
-         *p_in++;
-          p_out&#91;x*3+0&#93; = r;
-          p_out&#91;x*3+1&#93; = g;
-          p_out&#91;x*3+2&#93; = b;
-       &#125;
-    &#125;
+  /* Read file header, set default decompression parameters */
+       jpeg_read_header&#40;dinfo, TRUE&#41;;
 
-    p_out+= Width*3;
-  &#125;
+       /* Calculate output image dimensions so we can allocate space */
+       jpeg_calc_output_dimensions&#40;dinfo&#41;;
 
-  jpg = jpgCreateRAW&#40;out_buffer, Width, Height, 24&#41;;
-  ret = jpgCompressImageRAW&#40;jpg, &data&#41;;
-  fioWrite&#40; file_handle, data, ret &#41;;
-  jpgClose&#40;jpg&#41;;
+       priv->buffer = &#40;*dinfo->mem->alloc_small&#41; 
+               &#40;&#40;j_common_ptr&#41; dinfo, JPOOL_IMAGE, dinfo->output_width * dinfo->out_color_components&#41;;
 
-  fioClose&#40; file_handle &#41;;
+  /* Start decompressor */
+       jpeg_start_decompress&#40;dinfo&#41;;
 
-  free&#40;out_buffer&#41;;
+       // ntba2
+       if&#40; &#40;mode == JPG_WIDTH_FIX&#41; && &#40;dinfo->output_width % 4&#41; &#41;
+               jpg->width = dinfo->output_width - &#40;dinfo->output_width % 4&#41;;
+       else
+               jpg->width  = dinfo->output_width;
+
+       jpg->height = dinfo->output_height;
+       jpg->bpp    = dinfo->out_color_components * 8;
 
-  return 0;
+       /* All done. */
+       return&#40; priv->jerr.pub.num_warnings ? NULL &#58; jpg &#41;;
 &#125;
-
libjpg.h:

Code: Select all

diff -ur libjpg1/include/libjpg.h libjpg/include/libjpg.h
--- libjpg1/include/libjpg.h    2006-07-14 10&#58;58&#58;33.531250000 +0200
+++ libjpg/include/libjpg.h     2006-07-18 17&#58;10&#58;30.609375000 +0200
@@ -3,6 +3,13 @@
 
 #include <tamtypes.h>
 
+// ntba2
+//
+// JPG_WIDTH_FIX ensures Width is a multiple of four.
+//
+#define JPG_NORMAL             0x00
+#define        JPG_WIDTH_FIX   0x01
+
 typedef struct &#123;
        int width;
        int height;
@@ -11,15 +18,15 @@
        void *priv;
 &#125; jpgData;
 
-jpgData *jpgOpen&#40;char *filename&#41;;
-jpgData *jpgOpenRAW&#40;u8 *data, int size&#41;;
+jpgData *jpgOpen&#40; char *filename, int mode &#41;;
+jpgData *jpgOpenRAW&#40; u8 *data, int size, int mode &#41;;
+jpgData *jpgOpenFILE&#40; FILE *in_file, int mode &#41;;
 jpgData *jpgCreate&#40;char *filename, u8 *data, int width, int height, int bpp&#41;;
 jpgData *jpgCreateRAW&#40;u8 *data, int width, int height, int bpp&#41;;
 int      jpgCompressImage&#40;jpgData *jpg&#41;;
 int      jpgCompressImageRAW&#40;jpgData *jpg, u8 **dest&#41;;
 int      jpgReadImage&#40;jpgData *jpg, u8 *dest&#41;;
 void     jpgClose&#40;jpgData *jpg&#41;;
-int      jpgScreenshot&#40;const char* pFilename,unsigned int VramAdress,
-                      unsigned int Width, unsigned int Height, unsigned int Psm&#41;;
+int      jpgScreenshot&#40; const char* pFilename,unsigned int VramAdress, unsigned int Width, unsigned int Height, unsigned int Psm &#41;;
 
 #endif /* __LIBJPG_H__ */
It's my first diff creation, so if something is wrong don't hesitate to tell me.

Best regards

Polo