Hi,
attached is the patch to make rawstudio (rev. 4042) compile against
libpng-1.5
I hope it's backward compatible, but can't be 100% sure.
The other patch is an improvement for meta-x3f. It makes possible for
rawstudio to display thumbnails for SD15, DP1/2, SD1. Wathever,
decoding of raw datas is still not possible.
Regards,
Ille
Le Mon, 19 Sep 2011 20:01:36 +0200,
Ille <[email protected]> a écrit :
> I will make the patch tonight and submit it soon.
>
> I'm also tweeking the meta-x3f plugin. It seems the plugin loads the
> thumbnail from the last available uncompressed embedded image (ppm for
> SD9->SD14), which can be the full size preview. We could get better
> responsiveness if we make sure we load the embbeded thumbnail
> (whatever, it's of no gain with SD14, since the only uncompressed
> image is the thumbnail).
> Also, since SD15 (and DPs), the embbeded thumbnails are now in jpeg
> format. It shouldn't be hard to display the jpeg thumbnails in RS
> iconbox, but the loading of the raw datas from TRUE processors is not
> yet implemented in dcraw (I think) wich means RS can't actually
> process SD15, DP1 or DP2 raw files.
> I'm trying to get a better x3f loader.
>
> Regards,
> Ille
>
diff -urNb '--exclude=*svn*' rawstudio/plugins/load-gdk/exiv2-colorspace.cpp rawstudio-ille/plugins/load-gdk/exiv2-colorspace.cpp
--- rawstudio/plugins/load-gdk/exiv2-colorspace.cpp 2011-09-20 08:21:50.501262023 +0200
+++ rawstudio-ille/plugins/load-gdk/exiv2-colorspace.cpp 2011-09-20 09:47:04.667968240 +0200
@@ -125,11 +125,11 @@
int compression_type;
/* Extract embedded ICC profile */
- if (info_ptr->valid & PNG_INFO_iCCP)
+ if (png_get_valid(png_ptr, info_ptr, TRUE) & PNG_INFO_iCCP)
{
png_uint_32 retval = png_get_iCCP (png_ptr, info_ptr,
(png_charpp) &icc_profile_title, &compression_type,
- (png_charpp) &icc_profile, (png_uint_32*) &icc_profile_size);
+ (png_byte**) &icc_profile, (png_uint_32*) &icc_profile_size);
if (retval != 0)
{
RSIccProfile *icc = rs_icc_profile_new_from_memory((gchar*)icc_profile, icc_profile_size, TRUE);
diff -urNb '--exclude=*svn*' rawstudio/plugins/output-pngfile/output-pngfile.c rawstudio-ille/plugins/output-pngfile/output-pngfile.c
--- rawstudio/plugins/output-pngfile/output-pngfile.c 2011-09-20 08:21:50.531261647 +0200
+++ rawstudio-ille/plugins/output-pngfile/output-pngfile.c 2011-09-20 09:47:04.708967726 +0200
@@ -23,6 +23,7 @@
#include <gettext.h>
#include "config.h"
#include <png.h>
+#include <zlib.h>
#define RS_TYPE_PNGFILE (rs_pngfile_type)
#define RS_PNGFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_PNGFILE, RSPngfile))
@@ -198,7 +199,7 @@
rs_icc_profile_get_data(profile, &data, &data_length);
// FIXME: Insert correct profile name
- png_set_iCCP(png_ptr, info_ptr, "Profile name", PNG_COMPRESSION_TYPE_BASE, data, data_length);
+ png_set_iCCP(png_ptr, info_ptr, "Profile name", PNG_COMPRESSION_TYPE_BASE, (png_const_bytep)data, data_length);
if (pngfile->save16bit)
png_set_gAMA(png_ptr, info_ptr, 1.0);
}
diff -urNb '--exclude=*svn*' rawstudio/plugins/meta-x3f/Makefile.am rawstudio-ille/plugins/meta-x3f/Makefile.am
--- rawstudio/plugins/meta-x3f/Makefile.am 2011-09-20 08:21:50.550261406 +0200
+++ rawstudio-ille/plugins/meta-x3f/Makefile.am 2011-09-20 09:47:04.758967097 +0200
@@ -17,6 +17,6 @@
libdir = $(datadir)/rawstudio/plugins/
-meta_x3f_la_LIBADD = @PACKAGE_LIBS@
+meta_x3f_la_LIBADD = @LIBJPEG@
meta_x3f_la_LDFLAGS = -module -avoid-version
meta_x3f_la_SOURCES = x3f-meta.c
diff -urNb '--exclude=*svn*' rawstudio/plugins/meta-x3f/x3f-meta.c rawstudio-ille/plugins/meta-x3f/x3f-meta.c
--- rawstudio/plugins/meta-x3f/x3f-meta.c 2011-09-20 08:21:50.550261406 +0200
+++ rawstudio-ille/plugins/meta-x3f/x3f-meta.c 2011-09-20 09:47:04.758967097 +0200
@@ -15,11 +15,19 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * * 2011-09
+ * * Tâm Merlant <[email protected]>:
+ * * - Added thumbnailing and properties extraction for SD15, DP1, DP2 and SD1
+ * * - Modified the way the embedded thumbnails were found
+ * * - Made sure we load the embedded thumbnail and not the fullsize preview
+ *
*/
#include <rawstudio.h>
#include <glib.h>
#include <stdlib.h> /* atoi() */
+#include <jpeglib.h> /* for SD15/1 and DP1/2 */
/* http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf */
@@ -39,10 +47,16 @@
typedef enum x3f_data_format {
X3F_DATA_FORMAT_UNCOMPRESSED = 3,
+ X3F_DATA_FORMAT_HUFFMAN_WITH_TABLE = 6,
X3F_DATA_FORMAT_HUFFMAN = 11,
X3F_DATA_FORMAT_JPEG = 18,
} X3F_DATA_FORMAT;
+typedef enum x3f_type_of_image_data {
+ X3F_DATA_TYPE_PROCESSED = 2,
+ X3F_DATA_TYPE_RAW = 3,
+} X3F_TYPE_OF_IMAGE_DATA;
+
/*
* These structs is mostly used to define the file format - they can not
* be directly mapped to file because of endian differences on some platforms
@@ -108,6 +122,41 @@
guint value_offset; /* offset from start of CHARACTER data */
} __attribute__ ((packed)) X3F_PROPERTY_ENTRY;
+static GdkPixbuf * jpeg_load (guchar *content,
+ gsize length)
+{
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ guchar *image_data=NULL;
+ guchar *outbuf[1];
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+
+ jpeg_mem_src(&cinfo, content, length);
+ jpeg_read_header(&cinfo, TRUE);
+ jpeg_calc_output_dimensions (&cinfo);
+
+ if (!(image_data=malloc(sizeof(char)*cinfo.output_width*cinfo.output_height*3)))
+ return NULL;
+ outbuf[0]=image_data;
+
+ jpeg_start_decompress(&cinfo);
+
+ while (cinfo.output_scanline < cinfo.output_height){
+ jpeg_read_scanlines(&cinfo, (JSAMPARRAY)outbuf, 1);
+ outbuf[0]+=cinfo.output_width * 3;
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ return gdk_pixbuf_new_from_data (image_data, GDK_COLORSPACE_RGB,
+ FALSE, 8,
+ cinfo.output_width, cinfo.output_height,
+ cinfo.output_width * 3,
+ (GdkPixbufDestroyNotify) g_free, NULL);
+
+}
+
static gboolean
x3f_load_meta(const gchar *service, RAWFILE *rawfile, guint offset, RSMetadata *meta)
{
@@ -116,9 +165,12 @@
X3F_DIRECTORY_SECTION directory;
X3F_DIRECTORY_ENTRY directory_entry;
X3F_IMAGE_DATA image_data;
- guint start=0, width=0, height=0, rowstride=0;
+ guint start=0, width=0, height=0, rowstride=0, length=0;
+ X3F_TYPE_OF_IMAGE_DATA type_of_image_data;
+ X3F_DATA_FORMAT data_format;
GdkPixbuf *pixbuf = NULL, *pixbuf2 = NULL;
gdouble ratio=1.0;
+ gboolean thumb_ok=FALSE, prop_ok=FALSE;
/* Check if this is infact a Sigma-file */
if (!raw_strcmp(rawfile, G_STRUCT_OFFSET(X3F_FILE, identifier), "FOVb", 4))
@@ -178,22 +230,33 @@
file.directory_start+G_STRUCT_OFFSET(X3F_DIRECTORY_SECTION, number_of_entries),
&directory.number_of_entries);
- for(i=0;i<directory.number_of_entries;i++)
+ while (!(thumb_ok && prop_ok)) {
+ /* parse in reverse order to make sure the last added thumbnail and prop section get found first. See X3F spec for more info */
+ for(i=directory.number_of_entries;i>=0;i--)
{
gint offset = file.directory_start + sizeof(X3F_DIRECTORY_SECTION) + i * sizeof(X3F_DIRECTORY_ENTRY);
raw_get_uint(rawfile, offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, offset), &directory_entry.offset);
- raw_get_uint(rawfile, offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, length), &directory_entry.length);
-
- if (raw_strcmp(rawfile, offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, type), "IMA", 3))
+ if (raw_strcmp(rawfile, offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, type), "IMA", 3) && !thumb_ok)
{
/* Image Data */
- raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, data_format), &image_data.data_format);
- if (image_data.data_format == X3F_DATA_FORMAT_UNCOMPRESSED)
+ raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, type_of_image_data), &type_of_image_data);
+ if (type_of_image_data == X3F_DATA_TYPE_PROCESSED)
{
- start = directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, image_data);
raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, columns), &width);
+ if (width < 500) /* assume thumbnails are always less than 500pixels wide */
+ {
+ raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, data_format), &data_format);
raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, rows), &height);
raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, rowstride), &rowstride);
+ raw_get_uint(rawfile, directory_entry.offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, length), &length);
+ start = directory_entry.offset+G_STRUCT_OFFSET(X3F_IMAGE_DATA, image_data);
+ if (data_format == X3F_DATA_FORMAT_UNCOMPRESSED)
+ pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+start, GDK_COLORSPACE_RGB, FALSE, 8,
+ width, height, rowstride, NULL, NULL);
+ else if (data_format == X3F_DATA_FORMAT_JPEG)
+ pixbuf = jpeg_load (raw_get_map(rawfile)+start, length-28);
+ thumb_ok=TRUE;
+ }
}
}
else if (raw_strcmp(rawfile, offset+G_STRUCT_OFFSET(X3F_DIRECTORY_ENTRY, type), "PROP", 4))
@@ -244,7 +307,7 @@
}
else if (g_str_equal(name, "CAMMODEL"))
meta->model_ascii = g_strdup(value);
- else if (g_str_equal(name, "APERTURE")) /* Example: 8.000 */
+ else if (g_str_equal(name, "AP_DESC")) /* Example: 8.000 */
meta->aperture = rs_atof(value);
else if (g_str_equal(name, "SH_DESC")) /* Example: 1/60 */
{
@@ -265,14 +328,12 @@
if (value)
g_free(value);
}
+ prop_ok=TRUE;
+ }
}
}
}
}
-
- if (width > 0)
- pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+start, GDK_COLORSPACE_RGB, FALSE, 8,
- width, height, rowstride, NULL, NULL);
if (pixbuf)
{
_______________________________________________
Rawstudio-dev mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-dev