There is 3 diff for Makefile, libjpg.c, and libjpg.h.
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 {
-  struct jpeg_destination_mgr pub; /* public fields */
-
-  u8 *dest;
-  int size;
-
-  u8 *buffer;
+#include "jpeglib.h"
+#include "jerror.h"
+#include "setjmp.h"
+
+typedef struct {
+       struct jpeg_error_mgr pub;      /* "public" fields */
+
+       jmp_buf setjmp_buffer;  /* for return to caller */
+} custom_error_mgr;
+
+typedef struct {
+       struct jpeg_destination_mgr pub; /* public fields */
+
+       u8 *dest;
+       int size;
+
+       u8 *buffer;
 } _destination_mgr;
 
-typedef struct {
-  /* 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 {
+       /* 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;
 } jpgPrivate;
 
-int dLog=0;
-
-void __Log(char *fmt, ...) {
-       char buf[1024];
-       va_list list;
-
-/*     if (dLog == 0) {
-               dLog = fioOpen("host:dLog.txt", O_CREAT | O_WRONLY);
-       }
-*/
-       va_start(list, fmt);
-       vsprintf(buf, fmt, list);
-       va_end(list);
-       printf("%s", buf);
-//     fioWrite(dLog, buf, strlen(buf));
-
-//     fioClose(dLog);
-}
-
-
-void _src_init_source(j_decompress_ptr cinfo) {
+void _src_init_source( j_decompress_ptr cinfo )
+{
 }
 
-boolean _src_fill_input_buffer(j_decompress_ptr cinfo) {
-  return TRUE;
+boolean _src_fill_input_buffer( j_decompress_ptr cinfo )
+{
+       return TRUE;
 }
 
-void _src_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
+void _src_skip_input_data( j_decompress_ptr cinfo, long num_bytes )
+{
 }
 
-boolean _src_resync_to_restart(j_decompress_ptr cinfo, int desired) {
-  return TRUE;
+boolean _src_resync_to_restart( j_decompress_ptr cinfo, int desired )
+{
+       return TRUE;
 }
 
-void _src_term_source(j_decompress_ptr cinfo) {
+void _src_term_source( j_decompress_ptr cinfo )
+{
 }
-
-void _src_output_message(j_common_ptr cinfo) {
-  char buffer[JMSG_LENGTH_MAX];
-
-  /* Create the message */
-  (*cinfo->err->format_message) (cinfo, buffer);
-
-#ifdef DEBUG
-  printf("%s\n", buffer);
-#endif
+
+//
+// jpg_error_exit - this replaces the standard error_exit function
+//
+
+void custom_error_exit( j_common_ptr cinfo )
+{
+       custom_error_mgr *cerr = (custom_error_mgr*) cinfo->err;
+
+       /* Always display the message */
+       (*cinfo->err->output_message) (cinfo);
+
+       /* Let the memory manager delete any temp files before we die */
+       jpeg_destroy(cinfo);
+
+       // perform a long jump to previously saved environment
+       longjmp( cerr->setjmp_buffer, 1 );
+}
+
+
+//
+// custom_emit_message - this replaces the standard emit_message function
+//
+
+void custom_emit_message( j_common_ptr cinfo, int msg_level )
+{
+       struct jpeg_error_mgr *err = cinfo->err;
+
+       // this message is harmless, we will just ignore it
+       if( cinfo->err->msg_code == JWRN_EXTRANEOUS_DATA )
+               return;
+
+       if( msg_level < 0 )
+       {
+               /* 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( err->num_warnings == 0 || err->trace_level >= 3 )
+                       (*err->output_message) (cinfo);
+
+               /* Always count warnings in num_warnings. */
+               err->num_warnings++;
+       } else {
+               /* It's a trace message.  Show it if trace_level >= msg_level. */
+               if( err->trace_level >= msg_level )
+                       (*err->output_message) (cinfo);
+       }
+}
+
+jpgData *jpgOpenRAW( u8 *data, int size, int mode )
+{
+       struct jpeg_decompress_struct *dinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc( sizeof(jpgData) );
+       if( jpg == NULL )
+               return NULL;
+
+       memset( jpg, 0, sizeof(jpgData) );
+
+       priv = malloc( sizeof(jpgPrivate) );
+       if( priv == NULL )
+               return NULL;
+
+       jpg->priv       = priv;
+       dinfo           = &priv->dinfo;
+  
+       /* Initialize the JPEG decompression object with default error handling. */
+       dinfo->err      = jpeg_std_error(&priv->jerr.pub);
+
+       // 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( setjmp(priv->jerr.setjmp_buffer) ) {
+               jpgClose(jpg);
+               return NULL;
+       }
+
+       jpeg_create_decompress(dinfo);
+
+       /* 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(dinfo, TRUE);
+
+       /* Calculate output image dimensions so we can allocate space */
+       jpeg_calc_output_dimensions(dinfo);
+
+       priv->buffer = (*dinfo->mem->alloc_small) 
+               ((j_common_ptr) dinfo, JPOOL_IMAGE, dinfo->output_width * dinfo->out_color_components);
+
+       /* Start decompressor */
+       jpeg_start_decompress(dinfo);
+
+       // ntba2
+       if( (mode == JPG_WIDTH_FIX) && (dinfo->output_width % 4) )
+               jpg->width = dinfo->output_width - (dinfo->output_width % 4);
+       else
+               jpg->width  = dinfo->output_width;
+
+       jpg->height = dinfo->output_height;
+       jpg->bpp    = dinfo->out_color_components * 8;
+
+       /* All done. */
+       return( priv->jerr.pub.num_warnings ? NULL : jpg );
+}
+
+jpgData *jpgOpen( char *filename, int mode )
+{
+       jpgData *jpg;
+       jpgPrivate *priv;
+       u8 *data;
+       int size;
+       int fd;
+
+       fd = fileXioOpen( filename, O_RDONLY, 0 );
+       if( fd == -1 ) {
+               printf("jpgOpen: error opening '%s'\n", filename);
+               return NULL;
+       }
+
+       size = fileXioLseek( fd, 0, SEEK_END );
+       fileXioLseek( fd, 0, SEEK_SET );
+
+       data = (u8*)malloc(size);
+       if( data == NULL )
+               return NULL;
+
+       fileXioRead( fd, data, size );
+       fileXioClose(fd);
+
+       jpg = jpgOpenRAW( data, size, mode );
+       if( jpg == NULL )
+               return NULL;
+
+       priv = jpg->priv;
+       priv->data = data;
+
+       return jpg;
+}
+
+int jpgReadImage( jpgData *jpg, u8 *dest )
+{
+       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( setjmp(priv->jerr.setjmp_buffer) ) {
+               jpgClose(jpg);
+               return -1;
+       }
+
+       /* Process data */
+       while( priv->dinfo.output_scanline < priv->dinfo.output_height )
+       {
+               num_scanlines = jpeg_read_scanlines(&priv->dinfo, &priv->buffer, 1);
+
+               if( num_scanlines != 1 )
+                       break;
+
+               // ntba2
+               memcpy( dest, priv->buffer, jpg->width * priv->dinfo.out_color_components );
+               dest += width;
+       }
+
+       /* 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(&priv->dinfo);
+       jpeg_destroy_decompress(&priv->dinfo);
+
+       return( priv->jerr.pub.num_warnings ? -1 : 0 );
 }
 
-void _src_error_exit(j_common_ptr cinfo) {
-  /* Always display the message */
-  (*cinfo->err->output_message) (cinfo);
-
-  /* Let the memory manager delete any temp files before we die */
-  jpeg_destroy(cinfo);
+#define OUTPUT_BUF_SIZE        (64*1024)
 
-//  exit(EXIT_FAILURE);
+void _dest_init_destination( j_compress_ptr cinfo )
+{
 }
 
+boolean _dest_empty_output_buffer( j_compress_ptr cinfo )
+{
+
+       _destination_mgr *dest = (_destination_mgr*) cinfo->dest;
+
+       dest->dest = realloc(dest->dest, dest->size+OUTPUT_BUF_SIZE);
+       memcpy(dest->dest+dest->size, dest->buffer, OUTPUT_BUF_SIZE);
+
+       cinfo->dest->next_output_byte = dest->buffer;
+       cinfo->dest->free_in_buffer   = OUTPUT_BUF_SIZE;
+
+       dest->size+= OUTPUT_BUF_SIZE;
+
+       return TRUE;
+}
+
+void _dest_term_destination( j_compress_ptr cinfo )
+{
+       _destination_mgr *dest = (_destination_mgr*) cinfo->dest;
+       int size = OUTPUT_BUF_SIZE - cinfo->dest->free_in_buffer;
+
+       dest->dest = realloc(dest->dest, dest->size+size);
+       memcpy(dest->dest+dest->size, dest->buffer, size);
+
+       dest->size+= size;
+}
+
+jpgData *jpgCreateRAW( u8 *data, int width, int height, int bpp )
+{
+       struct jpeg_compress_struct *cinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc(sizeof(jpgData));
+       if( jpg == NULL )
+               return NULL;
+
+       memset(jpg, 0, sizeof(jpgData));
+       priv = malloc(sizeof(jpgPrivate));
+       if( priv == NULL )
+               return NULL;
+
+       jpg->priv = priv;
+       cinfo = &priv->cinfo;
+
+       /* Initialize the JPEG compression object with default error handling. */
+       cinfo->err = jpeg_std_error(&priv->jerr.pub);
+       jpeg_create_compress(cinfo);
+
+       priv->data = data;
+       priv->buffer = malloc(OUTPUT_BUF_SIZE);
+       if( priv->buffer == NULL )
+               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 = (struct jpeg_destination_mgr *)&priv->jdst;
+
+       cinfo->image_width      = width;                                        /* image width and height, in pixels */
+       cinfo->image_height = height;
+
+       if( bpp == 8 ) {
+               cinfo->input_components = 1;                            /* # of color components per pixel */
+               cinfo->in_color_space   = JCS_GRAYSCALE;        /* colorspace of input image */
+       }
+       else {
+               cinfo->input_components = 3;                            /* # of color components per pixel */
+               cinfo->in_color_space   = JCS_RGB;                      /* colorspace of input image */
+       }
+
+       jpeg_set_defaults(cinfo);
+
+       jpeg_set_quality( cinfo, 100, TRUE );
+       jpeg_start_compress(cinfo, TRUE);
+
+       jpg->width      = cinfo->image_width;
+       jpg->height = cinfo->image_height;
+       jpg->bpp        = cinfo->input_components*8;
+
+       /* All done. */
+       return( priv->jerr.pub.num_warnings ? NULL : jpg );
+}
+
+int jpgCompressImageRAW( jpgData *jpg, u8 **dest )
+{
+       jpgPrivate *priv = jpg->priv;
+       _destination_mgr *_dest = (_destination_mgr*) priv->cinfo.dest;
+       int width = priv->cinfo.image_width * priv->cinfo.input_components;
+       JSAMPROW row_pointer[1];        /* pointer to a single row */
+
+       _dest->dest = NULL;
+       _dest->size = 0;
+
+       while( priv->cinfo.next_scanline < priv->cinfo.image_height )
+       {
+               row_pointer[0] = & priv->data[priv->cinfo.next_scanline * width];
+               jpeg_write_scanlines(&priv->cinfo, row_pointer, 1);
+       }
+
+       jpeg_finish_compress(&priv->cinfo);
+       *dest = _dest->dest;
+
+       return( priv->jerr.pub.num_warnings ? -1 : _dest->size );
+}
+
+void jpgClose( jpgData *jpg )
+{
+       jpgPrivate *priv = jpg->priv;
+
+       if( priv->data )
+               free(priv->data);
+
+       free(priv);
+       free(jpg);
+}
+
+#define PS2SS_GSPSMCT32                0
+#define PS2SS_GSPSMCT24                1
+#define PS2SS_GSPSMCT16                2
+
+int jpgScreenshot( const char* pFilename,unsigned int VramAdress, unsigned int Width, unsigned int Height, unsigned int Psm )
+{
+       s32 file_handle;
+       u32 y;
+       static u32 in_buffer[1024*4];  // max 1024*32bit for a line, should be ok
+       u8 *out_buffer;
+       u8 *p_out;
+       jpgData *jpg;
+       u8 *data;
+       int ret;
+
+       file_handle = fileXioOpen( pFilename, O_CREAT | O_WRONLY, 0 );
+
+       // make sure we could open the file for output
+       if( file_handle < 0 )
+               return 0;
+
+       out_buffer = malloc( Width * Height * 3 );
+       if( out_buffer == NULL )
+               return 0;
+
+       p_out = out_buffer;
+
+       // Check if we have a tempbuffer, if we do we use it 
+       for( y = 0; y < Height; y++ )
+       {
+               ps2_screenshot( in_buffer, VramAdress, 0, y, Width, 1, Psm );
+
+               if( Psm == PS2SS_GSPSMCT16 )
+               {
+                       u32 x;
+                       u16* p_in  = (u16*)&in_buffer;
+        
+                       for( x = 0; x < Width; x++ )
+                       {
+                               u32 r = (p_in[x] & 31) << 3;
+                               u32 g = ((p_in[x] >> 5) & 31) << 3;
+                               u32 b = ((p_in[x] >> 10) & 31) << 3;
+
+                               p_out[x*3+0] = r;
+                               p_out[x*3+1] = g;
+                               p_out[x*3+2] = b;
+                       }
+               }
+               else
+                       if( Psm == PS2SS_GSPSMCT24 )
+                       {
+                               u32 x;
+                               u8* p_in  = (u8*)&in_buffer;
+
+                               for( x = 0; x < Width; x++ )
+                               {
+                                       u8 r =  *p_in++;
+                                       u8 g =  *p_in++;
+                                       u8 b =  *p_in++;
+
+                                       p_out[x*3+0] = r;
+                                       p_out[x*3+1] = g;
+                                       p_out[x*3+2] = b;
+                               }
+                       }
+                       else
+                       {
+                               u8 *p_in = (u8 *) &in_buffer;
+                               u32 x;
+
+                               for(x = 0; x < Width; x++)
+                               {
+                                       u8 r = *p_in++;
+                                       u8 g = *p_in++;
+                                       u8 b = *p_in++;
+
+                                       *p_in++;
+
+                                       p_out[x*3+0] = r;
+                                       p_out[x*3+1] = g;
+                                       p_out[x*3+2] = b;
+                               }
+                       }
+
+                       p_out+= Width*3;
+       }
+
+       jpg = jpgCreateRAW(out_buffer, Width, Height, 24);
+       ret = jpgCompressImageRAW(jpg, &data);
+
+       fileXioWrite( file_handle, data, ret );
+       jpgClose(jpg);
+
+       fileXioClose( file_handle );
+       free(out_buffer);
+
+       return 0;
+}
+
+/*
+ * 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(unsigned int)
+jpeg_getc (j_decompress_ptr dinfo)
+/* Read next byte */
+{
+  struct jpeg_source_mgr * datasrc = dinfo->src;
 
-jpgData *jpgOpenRAW(u8 *data, int size) {
-  struct jpeg_decompress_struct *dinfo;
-  jpgPrivate *priv;
-  jpgData *jpg;
-
-  jpg = malloc(sizeof(jpgData));
-  if (jpg == NULL) return NULL;
-
-  memset(jpg, 0, sizeof(jpgData));
-  priv = malloc(sizeof(jpgPrivate));
-  if (priv == NULL) return NULL;
-
-  jpg->priv = priv;
-  dinfo = &priv->dinfo;
-  /* Initialize the JPEG decompression object with default error handling. */
-  dinfo->err = jpeg_std_error(&priv->jerr);
-  jpeg_create_decompress(dinfo);
-
-  /* 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(dinfo, TRUE);
-
-  /* Calculate output image dimensions so we can allocate space */
-  jpeg_calc_output_dimensions(dinfo);
-
-  priv->buffer = (*dinfo->mem->alloc_small)
-      ((j_common_ptr) dinfo, JPOOL_IMAGE,
-       dinfo->output_width * dinfo->out_color_components);
-
-  /* Start decompressor */
-  jpeg_start_decompress(dinfo);
-
-  jpg->width  = dinfo->output_width;
-  jpg->height = dinfo->output_height;
-  jpg->bpp    = dinfo->out_color_components*8;
-
-  /* All done. */
-  return(priv->jerr.num_warnings ? NULL : jpg);
-}
-
-jpgData *jpgOpen(char *filename) {
-  jpgData *jpg;
-  jpgPrivate *priv;
-  u8 *data;
-  int size;
-  int fd;
-
-  fd = fioOpen(filename, O_RDONLY);
-  if (fd == -1) {
-    printf("jpgOpen: error opening '%s'\n", filename);
-    return NULL;
-  }
-  size = fioLseek(fd, 0, SEEK_END);
-  fioLseek(fd, 0, SEEK_SET);
-  data = (u8*)malloc(size);
-  if (data == NULL) return NULL;
-  fioRead(fd, data, size);
-  fioClose(fd);
-
-  jpg = jpgOpenRAW(data, size);
-  if (jpg == NULL) return NULL;
-  priv = jpg->priv;
-  priv->data = data;
-
-  return jpg;
-}
-
-int  jpgReadImage(jpgData *jpg, u8 *dest) {
-  JDIMENSION num_scanlines;
-  jpgPrivate *priv = jpg->priv;
-  int width = priv->dinfo.output_width * priv->dinfo.out_color_components;
-
-  /* Process data */
-  while (priv->dinfo.output_scanline < priv->dinfo.output_height) {
-    num_scanlines = jpeg_read_scanlines(&priv->dinfo, &priv->buffer, 1);
-       if (num_scanlines != 1) break;
-       memcpy(dest, priv->buffer, priv->dinfo.output_width * priv->dinfo.out_color_components);
-       dest+= width;
+  if (datasrc->bytes_in_buffer == 0) {
+    if (! (*datasrc->fill_input_buffer) (dinfo))
+      ERREXIT(dinfo, JERR_CANT_SUSPEND);
   }
-
-  /* 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(&priv->dinfo);
-  jpeg_destroy_decompress(&priv->dinfo);
-
-  return(priv->jerr.num_warnings ? -1 : 0);
+  datasrc->bytes_in_buffer--;
+  return GETJOCTET(*datasrc->next_input_byte++);
 }
 
-#define OUTPUT_BUF_SIZE        (64*1024)
-
-void _dest_init_destination(j_compress_ptr cinfo) {
-//__Log("_dest_init_destination\n");
-}
-
-boolean _dest_empty_output_buffer(j_compress_ptr cinfo) {
-  _destination_mgr *dest = (_destination_mgr*) cinfo->dest;
-
-//__Log("_dest_empty_output_buffer, %d\n", dest->size);
-  dest->dest = realloc(dest->dest, dest->size+OUTPUT_BUF_SIZE);
-  memcpy(dest->dest+dest->size, dest->buffer, OUTPUT_BUF_SIZE);
+METHODDEF(boolean)
+print_text_marker (j_decompress_ptr dinfo)
+{
+  boolean traceit = (dinfo->err->trace_level >= 1);
+  INT32 length;
+  unsigned int ch;
+  unsigned int lastch = 0;
+
+  length = jpeg_getc(dinfo) << 8;
+  length += jpeg_getc(dinfo);
+  length -= 2;                 /* discount the length word itself */
+
+  if (traceit) {
+    if (dinfo->unread_marker == JPEG_COM)
+      fprintf(stderr, "Comment, length %ld:\n", (long) length);
+    else                       /* assume it is an APPn otherwise */
+      fprintf(stderr, "APP%d, length %ld:\n",
+             dinfo->unread_marker - JPEG_APP0, (long) length);
+  }
 
-  cinfo->dest->next_output_byte = dest->buffer;
-  cinfo->dest->free_in_buffer   = OUTPUT_BUF_SIZE;
+  while (--length >= 0) {
+    ch = jpeg_getc(dinfo);
+    if (traceit) {
+      /* 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 (ch == '\r') {
+       fprintf(stderr, "\n");
+      } else if (ch == '\n') {
+       if (lastch != '\r')
+         fprintf(stderr, "\n");
+      } else if (ch == '\\') {
+       fprintf(stderr, "\\\\");
+      } else if (isprint(ch)) {
+       putc(ch, stderr);
+      } else {
+       fprintf(stderr, "\\%03o", ch);
+      }
+      lastch = ch;
+    }
+  }
 
-  dest->size+= OUTPUT_BUF_SIZE;
+  if (traceit)
+    fprintf(stderr, "\n");
 
   return TRUE;
 }
 
-void _dest_term_destination(j_compress_ptr cinfo) {
-  _destination_mgr *dest = (_destination_mgr*) cinfo->dest;
-  int size = OUTPUT_BUF_SIZE - cinfo->dest->free_in_buffer;
-
-//__Log("_dest_term_destination, %d\n", dest->size);
-  dest->dest = realloc(dest->dest, dest->size+size);
-  memcpy(dest->dest+dest->size, dest->buffer, size);
-
-  dest->size+= size;
-}
-
-jpgData *jpgCreateRAW(u8 *data, int width, int height, int bpp) {
-  struct jpeg_compress_struct *cinfo;
-  jpgPrivate *priv;
-  jpgData *jpg;
-
-//__Log("jpgCreateRAW\n");
-  jpg = malloc(sizeof(jpgData));
-  if (jpg == NULL) return NULL;
-
-//__Log("jpgCreateRAW1\n");
-  memset(jpg, 0, sizeof(jpgData));
-  priv = malloc(sizeof(jpgPrivate));
-  if (priv == NULL) return NULL;
-
-//__Log("jpgCreateRAW2\n");
-  jpg->priv = priv;
-  cinfo = &priv->cinfo;
-
-  /* Initialize the JPEG compression object with default error handling. */
-  cinfo->err = jpeg_std_error(&priv->jerr);
-  jpeg_create_compress(cinfo);
-
-//__Log("jpgCreateRAW3\n");
-  priv->data = data;
-  priv->buffer = malloc(OUTPUT_BUF_SIZE);
-  if (priv->buffer == NULL) return NULL;
-//__Log("jpgCreateRAW3 %p\n", priv->buffer);
-
-  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( FILE *in_file, int mode )
+{
+       struct jpeg_decompress_struct *dinfo;
+       jpgPrivate *priv;
+       jpgData *jpg;
+
+       jpg = malloc( sizeof(jpgData) );
+       if( jpg == NULL )
+               return NULL;
+
+       memset( jpg, 0, sizeof(jpgData) );
+
+       priv = malloc( sizeof(jpgPrivate) );
+       if( priv == NULL )
+               return NULL;
+
+       jpg->priv       = priv;
+       dinfo           = &priv->dinfo;
+  
+  /* Install default error handling. */
+       dinfo->err      = jpeg_std_error(&priv->jerr.pub);
+       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( setjmp(priv->jerr.setjmp_buffer) ) {
+               jpgClose(jpg);
+               return NULL;
+       }
+
+  /* Initialize the JPEG decompression. */
+       jpeg_create_decompress(dinfo);
+
+  /* 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 (see libjpeg.doc).
+   */
+  jpeg_set_marker_processor(dinfo, JPEG_COM, print_text_marker);
+  jpeg_set_marker_processor(dinfo, JPEG_APP0+12, print_text_marker);
 
-//printf("%p, %p\n", &priv->jdst.pub.next_output_byte, &priv->jdst);
   /* Specify data source for decompression */
-  cinfo->dest = (struct jpeg_destination_mgr *)&priv->jdst;
-
-//__Log("jpgCreateRAW4\n");
-  cinfo->image_width = width;  /* image width and height, in pixels */
-  cinfo->image_height = height;
-  if (bpp == 8) {
-    cinfo->input_components = 1;       /* # of color components per pixel */
-    cinfo->in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
-  } else {
-    cinfo->input_components = 3;       /* # of color components per pixel */
-    cinfo->in_color_space = JCS_RGB;    /* colorspace of input image */
-  }
+  jpeg_stdio_src(dinfo, in_file);
+       priv->jsrc = dinfo->src;
 
-//__Log("jpgCreateRAW5\n");
-  jpeg_set_defaults(cinfo);
-  jpeg_start_compress(cinfo, TRUE);
-
-  jpg->width = cinfo->image_width;
-  jpg->height = cinfo->image_height;
-  jpg->bpp = cinfo->input_components*8;
-//__Log("jpgCreateRAW6\n");
-
-  /* All done. */
-  return(priv->jerr.num_warnings ? NULL : jpg);
-}
-
-int jpgCompressImageRAW(jpgData *jpg, u8 **dest) {
-  jpgPrivate *priv = jpg->priv;
-  _destination_mgr *_dest = (_destination_mgr*) priv->cinfo.dest;
-  int width = priv->cinfo.image_width * priv->cinfo.input_components;
-  JSAMPROW row_pointer[1];     /* pointer to a single row */
-
-  _dest->dest = NULL;
-  _dest->size = 0;
-
-//__Log("jpgCompressImageRAW\n");
-  while (priv->cinfo.next_scanline < priv->cinfo.image_height) {
-    row_pointer[0] = & priv->data[priv->cinfo.next_scanline * width];
-//__Log("jpgCompressImageRAW %d %x (%d)\n", priv->cinfo.next_scanline, row_pointer[0], priv->jdst.pub.free_in_buffer);
-    jpeg_write_scanlines(&priv->cinfo, row_pointer, 1);
-  }
-//__Log("jpgCompressImageRAW2\n");
-  jpeg_finish_compress(&priv->cinfo);
-  *dest = _dest->dest;
-
-  return(priv->jerr.num_warnings ? -1 : _dest->size);
-}
-
-void jpgClose(jpgData *jpg) {
-  jpgPrivate *priv = jpg->priv;
-  if (priv->data) free(priv->data);
-  free(priv);
-  free(jpg);
-}
-
-#define PS2SS_GSPSMCT32           0
-#define PS2SS_GSPSMCT24           1
-#define PS2SS_GSPSMCT16           2
-
-int jpgScreenshot( const char* pFilename,unsigned int VramAdress,
-                         unsigned int Width, unsigned int Height, unsigned int Psm )
-{
-  s32 file_handle;
-  u32 y;
-  static u32 in_buffer[1024*4];  // max 1024*32bit for a line, should be ok
-  u8 *out_buffer;
-  u8 *p_out;
-  jpgData *jpg;
-  u8 *data;
-  int ret;
-
-  file_handle = fioOpen( pFilename, O_CREAT|O_WRONLY );
-
-  // make sure we could open the file for output
-
-  if( file_handle < 0 )
-    return 0;
-
-  out_buffer = malloc( Width*Height*3 );
-  if( out_buffer == NULL )
-    return 0;
-  p_out = out_buffer;
-
-  /////////////////////////////////////////////////////////////////////////////
-  // Check if we have a tempbuffer, if we do we use it 
-
-  for( y = 0; y < Height; y++ )
-  {
-    ps2_screenshot( in_buffer, VramAdress, 0, y, Width, 1, Psm );
-
-    if( Psm == PS2SS_GSPSMCT16 )
-    {
-      u32 x;
-      u16* p_in  = (u16*)&in_buffer;
-        
-      for( x = 0; x < Width; x++ )
-      {
-        u32 r = (p_in[x] & 31) << 3;
-        u32 g = ((p_in[x] >> 5) & 31) << 3;
-        u32 b = ((p_in[x] >> 10) & 31) << 3;
-         p_out[x*3+0] = r;
-         p_out[x*3+1] = g;
-         p_out[x*3+2] = b;
-      }
-    }
-    else
-    if( Psm == PS2SS_GSPSMCT24 )
-    {
-      u32 x;
-      u8* p_in  = (u8*)&in_buffer;
-        
-      for( x = 0; x < Width; x++ )
-      {
-        u8 r =  *p_in++;
-        u8 g =  *p_in++;
-        u8 b =  *p_in++;
-        p_out[x*3+0] = r;
-        p_out[x*3+1] = g;
-        p_out[x*3+2] = b;
-      }
-    }
-    else
-    {
-       u8 *p_in = (u8 *) &in_buffer;
-       u32 x;
-
-       for(x = 0; x < Width; x++)
-       {
-         u8 r = *p_in++;
-         u8 g = *p_in++;
-         u8 b = *p_in++;
-         *p_in++;
-          p_out[x*3+0] = r;
-          p_out[x*3+1] = g;
-          p_out[x*3+2] = b;
-       }
-    }
+  /* Read file header, set default decompression parameters */
+       jpeg_read_header(dinfo, TRUE);
 
-    p_out+= Width*3;
-  }
+       /* Calculate output image dimensions so we can allocate space */
+       jpeg_calc_output_dimensions(dinfo);
 
-  jpg = jpgCreateRAW(out_buffer, Width, Height, 24);
-  ret = jpgCompressImageRAW(jpg, &data);
-  fioWrite( file_handle, data, ret );
-  jpgClose(jpg);
+       priv->buffer = (*dinfo->mem->alloc_small) 
+               ((j_common_ptr) dinfo, JPOOL_IMAGE, dinfo->output_width * dinfo->out_color_components);
 
-  fioClose( file_handle );
+  /* Start decompressor */
+       jpeg_start_decompress(dinfo);
 
-  free(out_buffer);
+       // ntba2
+       if( (mode == JPG_WIDTH_FIX) && (dinfo->output_width % 4) )
+               jpg->width = dinfo->output_width - (dinfo->output_width % 4);
+       else
+               jpg->width  = dinfo->output_width;
+
+       jpg->height = dinfo->output_height;
+       jpg->bpp    = dinfo->out_color_components * 8;
 
-  return 0;
+       /* All done. */
+       return( priv->jerr.pub.num_warnings ? NULL : jpg );
 }
-
It's my first diff creation, so if something is wrong don't hesitate to tell me.