/* * UFRaw - Unidentified Flying Raw converter for digital camera images * * dcraw_api.cc - API for DCRaw * Copyright 2004-2008 by Udi Fuchs * * based on dcraw by Dave Coffin * http://www.cybercom.net/~dcoffin/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /* for sqrt() */ #include #include #include #include #include /*For _(String) definition - NKBJ*/ #include #include "dcraw_api.h" #include "dcraw.h" #include "mmap-hack.h" #define FORCC for (c=0; c < colors; c++) #define FC(filters,row,col) \ (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) extern "C" { int dcraw_open(dcraw_data *h, char *filename) { DCRaw *d = new DCRaw; #ifndef LOCALTIME putenv (const_cast("TZ=UTC")); #endif g_free(d->messageBuffer); d->messageBuffer = NULL; d->lastStatus = DCRAW_SUCCESS; d->verbose = 1; d->ifname = g_strdup(filename); d->ifname_display = g_filename_display_name(d->ifname); if (setjmp(d->failure)) { d->dcraw_message(DCRAW_ERROR,_("Fatal internal error\n")); h->message = d->messageBuffer; delete d; return DCRAW_ERROR; } if (!(d->ifp = fopen (d->ifname, "rb"))) { gchar *err_u8 = g_locale_to_utf8(strerror(errno), -1, NULL, NULL, NULL); d->dcraw_message(DCRAW_OPEN_ERROR,_("Cannot open file %s: %s\n"), d->ifname_display, err_u8); g_free(err_u8); h->message = d->messageBuffer; delete d; return DCRAW_OPEN_ERROR; } d->identify(); /* We first check if dcraw recognizes the file, this is equivalent * to 'dcraw -i' succeeding */ if (!d->make[0]) { d->dcraw_message(DCRAW_OPEN_ERROR,_("%s: unsupported file format.\n"), d->ifname_display); fclose(d->ifp); h->message = d->messageBuffer; delete d; return DCRAW_OPEN_ERROR; } /* Next we check if dcraw can decode the file */ if (!d->is_raw) { d->dcraw_message(DCRAW_OPEN_ERROR,_("Cannot decode file %s\n"), d->ifname_display); fclose(d->ifp); h->message = d->messageBuffer; delete d; return DCRAW_OPEN_ERROR; } if (d->load_raw == &DCRaw::kodak_ycbcr_load_raw) { d->height += d->height & 1; d->width += d->width & 1; } /* Pass class variables to the handler on two conditions: * 1. They are needed at this stage. * 2. They where set in identify() and won't change in load_raw() */ h->dcraw = d; h->ifp = d->ifp; h->height = d->height; h->width = d->width; h->fuji_width = d->fuji_width; h->fuji_step = sqrt(0.5); h->colors = d->colors; h->filters = d->filters; h->raw_color = d->raw_color; h->shrink = d->shrink = (h->filters!=0); h->pixel_aspect = d->pixel_aspect; /* copied from dcraw's main() */ switch ((d->flip+3600) % 360) { case 270: d->flip = 5; break; case 180: d->flip = 3; break; case 90: d->flip = 6; } h->flip = d->flip; h->toneCurveSize = d->tone_curve_size; h->toneCurveOffset = d->tone_curve_offset; h->toneModeOffset = d->tone_mode_offset; h->toneModeSize = d->tone_mode_size; g_strlcpy(h->make, d->make, 80); g_strlcpy(h->model, d->model, 80); h->iso_speed = d->iso_speed; h->shutter = d->shutter; h->aperture = d->aperture; h->focal_len = d->focal_len; h->timestamp = d->timestamp; h->raw.image = NULL; h->thumbType = unknown_thumb_type; h->message = d->messageBuffer; return d->lastStatus; } int dcraw_image_dimensions(dcraw_data *raw, int flip, int *height, int *width) { if (raw->fuji_width) { /* Copied from DCRaw's fuji_rotate() */ *width = (int)((raw->fuji_width - 1) / raw->fuji_step); *height = (int)((raw->height - raw->fuji_width + 1) / raw->fuji_step); } else { if (raw->pixel_aspect < 1) *height = (int)(raw->height / raw->pixel_aspect + 0.5); else *height = raw->height; if (raw->pixel_aspect > 1) *width = (int)(raw->width * raw->pixel_aspect + 0.5); else *width = raw->width; } if (flip & 4) { int tmp = *height; *height = *width; *width = tmp; } return DCRAW_SUCCESS; } int dcraw_load_raw(dcraw_data *h) { DCRaw *d = (DCRaw *)h->dcraw; int i, j; double dmin; g_free(d->messageBuffer); d->messageBuffer = NULL; d->lastStatus = DCRAW_SUCCESS; if (setjmp(d->failure)) { d->dcraw_message(DCRAW_ERROR,_("Fatal internal error\n")); h->message = d->messageBuffer; delete d; return DCRAW_ERROR; } h->raw.height = d->iheight = (h->height+h->shrink) >> h->shrink; h->raw.width = d->iwidth = (h->width+h->shrink) >> h->shrink; h->raw.image = d->image = g_new0(dcraw_image_type, d->iheight * d->iwidth + d->meta_length); d->meta_data = (char *) (d->image + d->iheight*d->iwidth); /* copied from the end of dcraw's identify() */ if (d->filters && d->colors == 3) { for (i=0; i < 32; i+=4) { if ((d->filters >> i & 15) == 9) d->filters |= 2 << i; if ((d->filters >> i & 15) == 6) d->filters |= 8 << i; } d->colors++; } h->raw.colors = d->colors; h->fourColorFilters = d->filters; d->dcraw_message(DCRAW_VERBOSE,_("Loading %s %s image from %s ...\n"), d->make, d->model, d->ifname_display); fseek (d->ifp, d->data_offset, SEEK_SET); (d->*d->load_raw)(); if (d->zero_is_bad) d->remove_zeroes(); d->bad_pixels(NULL); if (d->is_foveon) { d->foveon_interpolate(); h->raw.width = h->width = d->width; h->raw.height = h->height = d->height; } fclose(d->ifp); h->ifp = NULL; h->rgbMax = d->maximum; h->black = d->black; d->dcraw_message(DCRAW_VERBOSE,_("Black: %d, Maximum: %d\n"), d->black, d->maximum); dmin = DBL_MAX; for (i=0; icolors; i++) if (dmin > d->pre_mul[i]) dmin = d->pre_mul[i]; for (i=0; icolors; i++) h->pre_mul[i] = d->pre_mul[i]/dmin; if (h->colors==3) h->pre_mul[3] = 0; memcpy(h->cam_mul, d->cam_mul, sizeof d->cam_mul); memcpy(h->rgb_cam, d->rgb_cam, sizeof d->rgb_cam); double rgb_cam_transpose[4][3]; for (i=0; i<4; i++) for (j=0; j<3; j++) rgb_cam_transpose[i][j] = d->rgb_cam[j][i]; d->pseudoinverse (rgb_cam_transpose, h->cam_rgb, d->colors); h->message = d->messageBuffer; return d->lastStatus; } void dcraw_close(dcraw_data *h) { DCRaw *d = (DCRaw *)h->dcraw; g_free(h->raw.image); delete d; } void DCRaw::dcraw_message(int code, const char *format, ...) { } void dcraw_message(void *dcraw, int code, char *format, ...) { char *message; DCRaw *d = (DCRaw *)dcraw; va_list ap; va_start(ap, format); message = g_strdup_vprintf(format, ap); d->dcraw_message(code, message); va_end(ap); g_free(message); } } /*extern "C"*/