Add missing vim modeline.
[geeqie.git] / src / image_load_jpeg.c
index 854ca4d..fc00ffc 100644 (file)
@@ -1,9 +1,51 @@
+/*
+ * Geeqie
+ * (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2011 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+/* based on code from GdkPixbuf library - JPEG image loader
+ *
+ * Copyright (C) 1999 Michael Zucchi
+ * Copyright (C) 1999 The Free Software Foundation
+ * 
+ * Progressive loading code Copyright (C) 1999 Red Hat, Inc.
+ *
+ * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
+ *          Federico Mena-Quintero <federico@gimp.org>
+ *          Michael Fulbright <drmike@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
 
 #include "main.h"
+
 #include "image-load.h"
 #include "image_load_jpeg.h"
 #include "jpeg_parser.h"
 
+#ifdef HAVE_JPEG
+
 #include <setjmp.h>
 #include <jpeglib.h>
 #include <jerror.h>
@@ -181,6 +223,50 @@ void image_loader_jpeg_read_scanline(struct jpeg_decompress_struct *cinfo, gucha
                }
 }
 
+
+static void init_source (j_decompress_ptr cinfo) {}
+static boolean fill_input_buffer (j_decompress_ptr cinfo)
+{
+       ERREXIT(cinfo, JERR_INPUT_EMPTY);
+       return TRUE;
+}
+static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+       struct jpeg_source_mgr* src = (struct jpeg_source_mgr*) cinfo->src;
+
+       if (num_bytes > src->bytes_in_buffer)
+               {
+               ERREXIT(cinfo, JERR_INPUT_EOF);
+               }
+       else if (num_bytes > 0) 
+               {
+               src->next_input_byte += (size_t) num_bytes;
+               src->bytes_in_buffer -= (size_t) num_bytes;
+               }
+}
+static void term_source (j_decompress_ptr cinfo) {}
+static void set_mem_src (j_decompress_ptr cinfo, void* buffer, long nbytes)
+{
+       struct jpeg_source_mgr* src;
+
+       if (cinfo->src == NULL) 
+               {   /* first time for this JPEG object? */
+               cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) (
+                                       (j_common_ptr) cinfo, JPOOL_PERMANENT,
+                                       sizeof(struct jpeg_source_mgr));
+               }
+
+       src = (struct jpeg_source_mgr*) cinfo->src;
+       src->init_source = init_source;
+       src->fill_input_buffer = fill_input_buffer;
+       src->skip_input_data = skip_input_data;
+       src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
+       src->term_source = term_source;
+       src->bytes_in_buffer = nbytes;
+       src->next_input_byte = (JOCTET*)buffer;
+}
+
+
 static gboolean image_loader_jpeg_load (gpointer loader, const guchar *buf, gsize count, GError **error)
 {
        ImageLoaderJpeg *lj = (ImageLoaderJpeg *) loader;
@@ -198,9 +284,34 @@ static gboolean image_loader_jpeg_load (gpointer loader, const guchar *buf, gsiz
        MPOData *mpo = jpeg_get_mpo_data(buf, count);
        if (mpo && mpo->num_images > 1)
                {
-               lj->stereo = TRUE;
-               stereo_buf2 = (unsigned char *)buf + mpo->images[1].offset;
-               stereo_length = mpo->images[1].length;
+               guint i;
+               gint idx1 = -1, idx2 = -1;
+               guint num2 = 1;
+               
+               for (i = 0; i < mpo->num_images; i++)
+                       {
+                       if (mpo->images[i].type_code == 0x20002)
+                               {
+                               if (mpo->images[i].MPIndividualNum == 1)
+                                       {
+                                       idx1 = i;
+                                       }
+                               else if (mpo->images[i].MPIndividualNum > num2)
+                                       {
+                                       idx2 = i;
+                                       num2 = mpo->images[i].MPIndividualNum;
+                                       }
+                               }
+                       }
+                       
+               if (idx1 >= 0 && idx2 >= 0)
+                       {
+                       lj->stereo = TRUE;
+                       stereo_buf2 = (unsigned char *)buf + mpo->images[idx2].offset;
+                       stereo_length = mpo->images[idx2].length;
+                       buf = (unsigned char *)buf + mpo->images[idx1].offset;
+                       count = mpo->images[idx1].length;
+                       }
                }
        jpeg_mpo_data_free(mpo);
 
@@ -225,7 +336,7 @@ static gboolean image_loader_jpeg_load (gpointer loader, const guchar *buf, gsiz
        
        jpeg_create_decompress(&cinfo);
 
-       jpeg_mem_src(&cinfo, (unsigned char *)buf, count);
+       set_mem_src(&cinfo, (unsigned char *)buf, count);
 
 
        jpeg_read_header(&cinfo, TRUE);
@@ -233,7 +344,7 @@ static gboolean image_loader_jpeg_load (gpointer loader, const guchar *buf, gsiz
        if (lj->stereo)
                {
                jpeg_create_decompress(&cinfo2);
-               jpeg_mem_src(&cinfo2, stereo_buf2, stereo_length);
+               set_mem_src(&cinfo2, stereo_buf2, stereo_length);
                jpeg_read_header(&cinfo2, TRUE);
                
                if (cinfo.image_width != cinfo2.image_width ||
@@ -386,3 +497,7 @@ void image_loader_backend_set_jpeg(ImageLoaderBackend *funcs)
 
 
 
+#endif
+
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */