[CinePaint] rawphoto plugin and newer dcraw
| Newsgroups | gmane.comp.video.cinepaint.user |
|---|---|
| Message-ID | <[email protected]> |
I have recently been recompiling a lot of packages for one of the computers at home and discovered that the rawphoto plugin was broken in my fresh installation of Cinepaint-0.21. After a little digging the culprit turned out to be dcraw, which has changed command line options for color balance. Specifically, rather than using -r -l -b -k those options are now rolled into one, so you now need to pass the program -r followed by four values. I'm not sure when Dave Coffin made this change but my old dcraw binary (7.94) is still command line compatible with the cinepaint plugin. The easy answer would be to just use the old version of dcraw, but with added support for newer model cameras and the ability to output in TIFF format running a newer version is pretty desireable now. I've attached my dirty hack to get it working, problem is that this version won't be compatible with older versions of dcraw. Nathan ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Cinepaint-users mailing list Cinepaint-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/cinepaint-users
rawphoto.c
(text/x-csrc, 10.7 KB)
/*
Raw photo loader plugin for The GIMP
by Dave Coffin at cybercom dot net, user dcoffin
http://www.cybercom.net/~dcoffin/
$Revision: 1.6 $
$Date: 2006/04/06 11:12:36 $
This code is licensed under the same terms as The GIMP.
To simplify maintenance, it calls my command-line "dcraw"
program to do the actual decoding.
To install locally:
gimptool --install rawphoto.c
To install globally:
gimptool --install-admin rawphoto.c
To build without installing:
gcc -o rawphoto rawphoto.c `gtk-config --cflags --libs` -lgimp -lgimpui
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#ifdef GIMP_VERSION
#error "NOT HERE"
#else
#include <lib/plugin_main.h>
#include <lib/ui.h>
#include <libgimp/stdplugins-intl.h>
#include <lib/dialog.h>
#include <lib/widgets.h>
#endif
#define PLUG_IN_VERSION "1.1.5-cp-0.1 - 19 April 2004 (cp 10.Mai 2004)"
static void query(void);
static void run(gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gint load_dialog (gchar *name);
static gint32 load_image (gchar *filename);
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_procedure */
NULL, /* quit_procedure */
query, /* query_procedure */
run, /* run_procedure */
};
static struct {
gboolean check_val[7];
gfloat spin_val[4];
int used_bits;
gchar i_profile[1024]; /* input profile */
gchar o_profile[1024]; /* output profile */
} cfg = {
{ FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE },
{ 2.2, 1.0, 1.0, 1.0 },
16
};
MAIN ()
static void query (void)
{
static GimpParamDef load_args[] =
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
{ GIMP_PDB_STRING, "raw_filename", "The name of the file to load" },
};
static GimpParamDef load_return_vals[] =
{
{ GIMP_PDB_IMAGE, "image", "Output image" },
};
static gint num_load_args =
sizeof load_args / sizeof load_args[0];
static gint num_load_return_vals =
sizeof load_return_vals / sizeof load_return_vals[0];
gimp_install_procedure ("file_rawphoto_load",
"Loads raw digital camera files",
"This plug-in loads raw digital camera files.",
"Dave Coffin at cybercom dot net, user dcoffin",
"Copyright 2003 by Dave Coffin",
PLUG_IN_VERSION,
"<Load>/rawphoto",
NULL,
GIMP_PLUGIN,
num_load_args,
num_load_return_vals,
load_args,
load_return_vals);
gimp_register_load_handler ("file_rawphoto_load",
"bay,bmq,cr2,crw,cs1,dc2,dcr,dng,fff,jpg,k25,kdc,mos,mrw,nef,orf,pef,raf,raw,rdc,srf,sti,tif,tiff,x3f", "");
}
static void run (gchar *name,
gint nparams,
GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[2];
GimpRunModeType run_mode;
GimpPDBStatusType status;
gint32 image_id = -1;
gchar *command, *fname;
int stat;
INIT_I18N_UI();
*nreturn_vals = 1;
*return_vals = values;
status = GIMP_PDB_CALLING_ERROR;
if (strcmp (name, "file_rawphoto_load")) goto done;
status = GIMP_PDB_EXECUTION_ERROR;
fname = param[1].data.d_string;
command = g_malloc (strlen(fname)+20);
if (!command) goto done;
/*
Is the file really a raw photo? If not, try loading it
as a regular JPEG or TIFF.
*/
sprintf (command, "dcraw -i '%s'\n", fname);
fputs (command, stderr);
stat = system (command);
g_free (command);
if (stat) {
if (stat > 0x200)
g_message (_("The \"rawphoto\" plugin won't work because "
"there is no \"dcraw\" executable in your path."));
if (!strcasecmp (fname + strlen(fname) - 4, ".jpg"))
*return_vals = gimp_run_procedure2
("file_jpeg_load", nreturn_vals, nparams, param);
else
*return_vals = gimp_run_procedure2
("file_tiff_load", nreturn_vals, nparams, param);
return;
}
gimp_get_data ("plug_in_rawphoto", &cfg);
status = GIMP_PDB_CANCEL;
run_mode = param[0].data.d_int32;
if (run_mode == GIMP_RUN_INTERACTIVE)
if (!load_dialog (param[1].data.d_string)) goto done;
status = GIMP_PDB_EXECUTION_ERROR;
image_id = load_image (param[1].data.d_string);
if (image_id == -1) goto done;
*nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE;
values[1].data.d_image = image_id;
status = GIMP_PDB_SUCCESS;
gimp_set_data ("plug_in_rawphoto", &cfg, sizeof cfg);
done:
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
}
#define byteswap(c) do { t=(c)[0]; (c)[0]=(c)[1]; (c)[1]=t; } while(0)
static gint32 load_image (gchar *filename)
{
int tile_height, width, height, row, nrows, depth;
int bpp_gimp, bpp_ppm, px;
FILE *pfp;
gint32 image, layer;
GimpDrawable *drawable;
GimpPixelRgn pixel_region;
guchar *pixel;
char *command, nl;
guchar t;
guint16 *val;
/*setlocale (LC_NUMERIC, "C");*/
command = g_malloc (strlen(filename)+100);
if (!command) return -1;
/* gamma now is handled internally - Kai-Uwe */
sprintf (command,
"dcraw -4 -v -c%s%s%s%s%s%s%s "/*-g %0.2f*/ "-b %0.2f -r %0.2f %0.2f %0.2f %0.2f '%s'\n",
cfg.check_val[0] ? " -q 0 -n":"",
cfg.check_val[1] ? " -h":"",
cfg.check_val[2] ? " -f":"",
cfg.check_val[3] ? " -d":"",
cfg.check_val[4] ? " -a":"",
cfg.check_val[5] ? " -w":"",
cfg.check_val[6] ? "":" -m",
/*cfg.spin_val[0],*/ cfg.spin_val[1], cfg.spin_val[2], cfg.spin_val[3],
filename );
fputs (command, stderr);
pfp = popen (command, "r");
g_free (command);
if (!pfp) {
perror ("dcraw");
return -1;
}
if (fscanf (pfp, "P6 %d %d %d%c", &width, &height, &depth, &nl) != 4) {
pclose (pfp);
g_message ("Not a raw digital camera image.%d %d %d %d\n",width,height,depth,nl);
return -1;
}
if(depth < 256) { bpp_ppm = 3; } else { bpp_ppm = 6; }
image = gimp_image_new (width, height, bpp_ppm == 3 ? RGB : U16_RGB);
if (image == -1) {
pclose (pfp);
g_message ("Can't allocate new image.\n");
return -1;
}
gimp_image_set_filename (image, filename);
/* Create the "background" layer to hold the image... */
layer = gimp_layer_new (image, _("Background"), width, height,
bpp_ppm == 3 ? RGB_IMAGE : U16_RGB_IMAGE,
100, GIMP_NORMAL_MODE);
gimp_image_add_layer (image, layer, 0);
/* Get the drawable and set the pixel region for our load... */
drawable = gimp_drawable_get (layer);
gimp_pixel_rgn_init (&pixel_region, drawable, 0, 0, drawable->width,
drawable->height, TRUE, FALSE);
bpp_gimp = pixel_region.bpp;
if(bpp_gimp != bpp_ppm) {
pclose (pfp);
g_message ("Wrong depth for new image.\n");
return -1;
}
/* Temporary buffers... */
tile_height = get_lib_tile_height();
pixel = g_new (guchar, tile_height * width * bpp_gimp);
/* Load the image... */
for (row = 0; row < height; row += tile_height) {
nrows = height - row;
if (nrows > tile_height)
nrows = tile_height;
fread (pixel, width * bpp_ppm, nrows, pfp);
if(bpp_ppm == 6) for(px = 0; px < width * nrows * 3; px++) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
byteswap(pixel + 2*px);
#endif
/* changed brightness / gamma handling - Kai-Uwe */
val = ((guint16*) &(pixel [2*px]));
/* doing an simple bitshift here is is better undoable */
if (cfg.used_bits < 16)
*val = *val << (16 - cfg.used_bits);
/* gamma */
*val = pow ((float)*val/65535.0, 1.0/cfg.spin_val[0]) * 65535.0;
}
printf (".");
gimp_pixel_rgn_set_rect (&pixel_region, pixel, 0, row, width, nrows);
}
pclose (pfp);
g_free (pixel);
gimp_drawable_flush (drawable);
gimp_drawable_detach (drawable);
return image;
}
/* this is set to true after OK click in any dialog */
gboolean result = FALSE;
static void callback_ok (GtkWidget * widget, gpointer data)
{
result = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
#define NCHECK (sizeof cfg.check_val / sizeof (gboolean))
#include <gdk/gdkkeysyms.h>
gint load_dialog (gchar * name)
{
GtkWidget *dialog;
GtkWidget *table;
GtkObject *adj;
GtkWidget *widget;
int i;
static const char *label[11];
label[0] = _("Quick interpolation");
label[1] = _("Half-size interpolation");
label[2] = _("Four color interpolation");
label[3] = _("Grayscale document");
label[4] = _("Automatic white balance");
label[5] = _("Camera white balance");
label[6] = _("Convert to sRGB");
label[7] = _("Gamma");
label[8] = _("Brightness");
label[9] = _("Red Multiplier");
label[10] = _("Blue Multiplier");
if (!strcasecmp (name + strlen(name) - 4, ".dng"))
cfg.used_bits = 16;
gimp_ui_init ("rawphoto", TRUE);
dialog = gimp_dialog_new (_("Raw Photo Loader 1.0"), "rawphoto",
gimp_standard_help_func, "",
GTK_WIN_POS_MOUSE,
FALSE, TRUE, FALSE,
_("OK"), callback_ok, NULL, NULL, NULL, TRUE,
FALSE, _("Cancel"), gtk_widget_destroy, NULL,
1, NULL, FALSE, TRUE, NULL);
gtk_signal_connect
(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
table = gtk_table_new (8, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER(table), 6);
gtk_box_pack_start
(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
for (i=0; i < NCHECK; i++) {
widget = gtk_check_button_new_with_label
(_(label[i]));
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (widget), cfg.check_val[i]);
gtk_table_attach
(GTK_TABLE(table), widget, 0, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (widget), "toggled",
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
&cfg.check_val[i]);
gtk_widget_show (widget);
}
# if 0
for (i=NCHECK; i < NCHECK+4; i++) {
widget = gtk_label_new (_(label[i]));
gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
gtk_misc_set_padding (GTK_MISC (widget), 10, 0);
gtk_table_attach
(GTK_TABLE(table), widget, 0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (widget);
widget = gimp_spin_button_new
(&adj, cfg.spin_val[i-NCHECK], 0.01, 4.0, 0.01, 0.1, 0.1, 0.1, 2);
gtk_table_attach
(GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (gimp_float_adjustment_update),
&cfg.spin_val[i-NCHECK]);
gtk_widget_show (widget);
}
/* look in lib/widgets.h Kai-Uwe */
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 11,
_("bit depth:"), 100, 0,
cfg.used_bits, 8, 16, 1, 1, 0,
TRUE, 0, 0,
NULL, NULL);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
&cfg.used_bits);
# endif
gtk_widget_show (dialog);
gtk_main();
gdk_flush();
return result;
}