Update of /cvsroot/ufraw/ufraw
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv10053
Modified Files:
ufraw-gimp.c ufraw.h ufraw_lens_ui.c ufraw_preview.c
ufraw_ufraw.c ufraw_ui.h ufraw_writer.c
Log Message:
Resize canvas to fit to lensfun transformations.
Index: ufraw_writer.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_writer.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- ufraw_writer.c 23 Jan 2010 05:00:59 -0000 1.70
+++ ufraw_writer.c 5 Feb 2010 23:22:16 -0000 1.71
@@ -196,36 +196,35 @@
#endif /*HAVE_LIBPNG*/
void ufraw_write_image_data(
- ufraw_data *uf,
- void * volatile out,
- int width, int height, int left, int top, int bitDepth, int grayscaleMode,
- int (*row_writer) (ufraw_data *, void * volatile, void *, int, int, int,
int, int))
+ ufraw_data *uf, void * volatile out,
+ const UFRectangle *Crop, int bitDepth, int grayscaleMode,
+ int (*row_writer)(ufraw_data *, void * volatile, void *, int, int, int,
int, int))
{
int row, row0;
int rowStride = uf->Images[ufraw_first_phase].width;
ufraw_image_type *rawImage =
(ufraw_image_type *)uf->Images[ufraw_first_phase].buffer;
int byteDepth = (bitDepth+7)/8;
- guint8 pixbuf8[width * 3 * byteDepth * DEVELOP_BATCH];
+ guint8 pixbuf8[Crop->width * 3 * byteDepth * DEVELOP_BATCH];
- progress(PROGRESS_SAVE, -height);
- for (row0 = 0; row0 < height; row0 += DEVELOP_BATCH) {
+ progress(PROGRESS_SAVE, -Crop->height);
+ for (row0 = 0; row0 < Crop->height; row0 += DEVELOP_BATCH) {
progress(PROGRESS_SAVE, DEVELOP_BATCH);
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(row)
#endif
for (row = 0; row < DEVELOP_BATCH; row++) {
- if (row + row0 >= height)
+ if (row + row0 >= Crop->height)
continue;
- guint8 *rowbuf = &pixbuf8[row * width * 3 * byteDepth];
- develop(rowbuf, rawImage[(top+row+row0)*rowStride+left],
- uf->developer, bitDepth, width);
+ guint8 *rowbuf = &pixbuf8[row * Crop->width * 3 * byteDepth];
+ develop(rowbuf, rawImage[(Crop->y+row+row0)*rowStride+Crop->x],
+ uf->developer, bitDepth, Crop->width);
if (grayscaleMode)
- grayscale_buffer(rowbuf, width, bitDepth);
+ grayscale_buffer(rowbuf, Crop->width, bitDepth);
}
- int batchHeight = MIN(height-row0, DEVELOP_BATCH);
- if ( row_writer(uf, out, pixbuf8, row0, width, batchHeight,
- grayscaleMode, bitDepth) != UFRAW_SUCCESS )
+ int batchHeight = MIN(Crop->height-row0, DEVELOP_BATCH);
+ if (row_writer(uf, out, pixbuf8, row0, Crop->width, batchHeight,
+ grayscaleMode, bitDepth) != UFRAW_SUCCESS)
break;
}
}
@@ -237,7 +236,6 @@
#ifdef HAVE_LIBCFITSIO
fitsfile *fitsFile;
#endif
- int width, height, left, top;
char * volatile confFilename=NULL;
int grayscaleMode = uf->conf->grayscaleMode != grayscale_none;
ufraw_message_reset(uf);
@@ -323,30 +321,25 @@
}
// TODO: error handling
ufraw_convert_image(uf);
- ufraw_image_data *FirstImage = &uf->Images[ufraw_first_phase];
- left = uf->conf->CropX1 * FirstImage->width / uf->rotatedWidth;
- top = uf->conf->CropY1 * FirstImage->height / uf->rotatedHeight;
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(uf, &Crop);
volatile int BitDepth = uf->conf->profile[out_profile]
[uf->conf->profileIndex[out_profile]].BitDepth;
if ( BitDepth!=16 ) BitDepth = 8;
- width = (uf->conf->CropX2 - uf->conf->CropX1)
- * FirstImage->width / uf->rotatedWidth;
- height = (uf->conf->CropY2 - uf->conf->CropY1)
- * FirstImage->height / uf->rotatedHeight;
if ( uf->conf->type==ppm_type && BitDepth==8 ) {
fprintf(out, "P%c\n%d %d\n%d\n",
- grayscaleMode ? '5' : '6', width, height, 0xFF);
- ufraw_write_image_data(uf, out, width, height, left, top,
- BitDepth, grayscaleMode, ppm_row_writer);
+ grayscaleMode ? '5' : '6', Crop.width, Crop.height, 0xFF);
+ ufraw_write_image_data(uf, out, &Crop, BitDepth, grayscaleMode,
+ ppm_row_writer);
} else if ( uf->conf->type==ppm_type && BitDepth==16 ) {
fprintf(out, "P%c\n%d %d\n%d\n",
- grayscaleMode ? '5' : '6', width, height, 0xFFFF);
- ufraw_write_image_data(uf, out, width, height, left, top,
- BitDepth, grayscaleMode, ppm_row_writer);
+ grayscaleMode ? '5' : '6', Crop.width, Crop.height, 0xFFFF);
+ ufraw_write_image_data(uf, out, &Crop, BitDepth, grayscaleMode,
+ ppm_row_writer);
#ifdef HAVE_LIBTIFF
} else if ( uf->conf->type==tiff_type ) {
- TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
- TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
+ TIFFSetField(out, TIFFTAG_IMAGEWIDTH, Crop.width);
+ TIFFSetField(out, TIFFTAG_IMAGELENGTH, Crop.height);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, grayscaleMode ? 1 : 3);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitDepth);
@@ -395,8 +388,8 @@
}
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, 0));
- ufraw_write_image_data(uf, out, width, height, left, top,
- BitDepth, grayscaleMode, tiff_row_writer);
+ ufraw_write_image_data(uf, out, &Crop, BitDepth, grayscaleMode,
+ tiff_row_writer);
#endif /*HAVE_LIBTIFF*/
#ifdef HAVE_LIBJPEG
@@ -413,8 +406,8 @@
cinfo.client_data = uf;
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, out);
- cinfo.image_width = width;
- cinfo.image_height = height;
+ cinfo.image_width = Crop.width;
+ cinfo.image_height = Crop.height;
if (grayscaleMode) {
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
@@ -481,8 +474,8 @@
}
}
- ufraw_write_image_data(uf, &cinfo, width, height, left, top,
- 8, grayscaleMode, jpeg_row_writer);
+ ufraw_write_image_data(uf, &cinfo, &Crop, 8, grayscaleMode,
+ jpeg_row_writer);
if ( ufraw_is_error(uf) ) {
char *message = g_strdup(ufraw_get_message(uf));
@@ -510,7 +503,7 @@
png_destroy_write_struct(&png, &info);
} else {
png_init_io(png, out);
- png_set_IHDR(png, info, width, height, BitDepth,
+ png_set_IHDR(png, info, Crop.width, Crop.height, BitDepth,
grayscaleMode ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
@@ -573,8 +566,8 @@
if (BitDepth != 8 && G_BYTE_ORDER==G_LITTLE_ENDIAN )
png_set_swap(png); // Swap byte order to big-endian
- ufraw_write_image_data(uf, png, width, height, left, top,
- BitDepth, grayscaleMode, png_row_writer);
+ ufraw_write_image_data(uf, png, &Crop, BitDepth, grayscaleMode,
+ png_row_writer);
png_write_end(png, NULL);
png_destroy_write_struct(&png, &info);
@@ -593,8 +586,8 @@
int naxis = 3; // 3-dimensional image
int status = 0; // status variable for fitsio
- long naxes[3] = { width, height, 3 };
- long dim = width * height;
+ long naxes[3] = { Crop.width, Crop.height, 3 };
+ long dim = Crop.width * Crop.height;
long offset = 0;
image = g_new(guint16, 3 * dim);
@@ -609,13 +602,13 @@
// Avoid FITS images being saved upside down
ufraw_flip_image(uf, 2);
- progress(PROGRESS_SAVE, -height);
- for (row=0; row<height; row++) {
+ progress(PROGRESS_SAVE, -Crop.height);
+ for (row=0; row<Crop.height; row++) {
progress(PROGRESS_SAVE, 1);
- for (i=0; i < width; i++)
+ for (i=0; i < Crop.width; i++)
{
- offset = row*width + i;
- develop_linear(rawImage[(top+row)*rowStride+left+i], pixbuf16,
+ offset = row*Crop.width + i;
+ develop_linear(rawImage[(Crop.y+row)*rowStride+Crop.x+i],
pixbuf16,
uf->developer);
int c;
for (c=0; c<3; c++) {
Index: ufraw_lens_ui.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_lens_ui.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- ufraw_lens_ui.c 23 Jan 2010 05:00:58 -0000 1.24
+++ ufraw_lens_ui.c 5 Feb 2010 23:22:15 -0000 1.25
@@ -334,6 +334,7 @@
ufraw_invalidate_layer(data->UF, ufraw_first_phase);
else
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
@@ -610,6 +611,7 @@
preview_data *data = get_preview_data (adj);
*valuep = gtk_adjustment_get_value (adj);
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
@@ -619,6 +621,7 @@
preview_data *data = get_preview_data (button);
gtk_adjustment_set_value (data->LensScaleAdjustment, 0.0);
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
@@ -635,6 +638,7 @@
gtk_adjustment_set_value (data->LensScaleAdjustment,
log (cs * as) / log (2.0));
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
}
@@ -891,6 +895,7 @@
lf_lens_add_calib_distortion (CFG->lens, &CFG->lens_distortion);
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
@@ -929,6 +934,7 @@
gtk_widget_show_all (data->LensDistortionTable);
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
@@ -1001,6 +1007,7 @@
gtk_label_set_text (GTK_LABEL (data->LensFromGeometryDesc), details);
ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
render_preview (data);
}
Index: ufraw_preview.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_preview.c,v
retrieving revision 1.332
retrieving revision 1.333
diff -u -d -r1.332 -r1.333
--- ufraw_preview.c 4 Feb 2010 05:59:57 -0000 1.332
+++ ufraw_preview.c 5 Feb 2010 23:22:15 -0000 1.333
@@ -507,20 +507,6 @@
return 0;
}
-/* Scale crop coordinates to final image coordinates */
-void scale_crop_to_final_image(ufraw_data *uf,
- int *x1, int *x2, int *y1, int *y2)
-{
- ufraw_image_data *img = ufraw_get_image(uf, ufraw_develop_phase, FALSE);
-
- float scale_x = ((float)img->width) / uf->rotatedWidth;
- float scale_y = ((float)img->height) / uf->rotatedHeight;
- *x1 = MAX(floor(uf->conf->CropX1 * scale_x), 0);
- *x2 = MIN(ceil(uf->conf->CropX2 * scale_x), img->width);
- *y1 = MAX(floor(uf->conf->CropY1 * scale_y), 0);
- *y2 = MIN(ceil(uf->conf->CropY2 * scale_y), img->height);
-}
-
/* Modify the preview image to mark crop and spot areas.
* Note that all coordinate intervals are semi-inclusive, e.g.
* X1 <= pixels < X2 and Y1 <= pixels < Y2
@@ -553,10 +539,10 @@
gboolean blinkUnder = CFG->underExp &&
( !CFG->blinkOverUnder || (data->OverUnderTicker & 3) == 3 );
- int CropX1, CropX2, CropY1, CropY2;
- scale_crop_to_final_image(data->UF, &CropX1, &CropX2, &CropY1, &CropY2);
- int CropWidth = CropX2 - CropX1;
- int CropHeight = CropY2 - CropY1;
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(data->UF, &Crop);
+ int CropX2 = Crop.x + Crop.width;
+ int CropY2 = Crop.y + Crop.height;
int drawLines = CFG->drawLines + 1;
/* Scale spot image coordinates to pixbuf coordinates */
@@ -605,24 +591,24 @@
continue;
}
/* Draw white frame around crop area */
- if ( ((yy==CropY1-1 || yy==CropY2) && xx>=CropX1-1 && xx<=CropX2) ||
- ((xx==CropX1-1 || xx==CropX2) && yy>=CropY1-1 && yy<=CropY2) )
+ if ( ((yy==Crop.y-1 || yy==CropY2) && xx>=Crop.x-1 && xx<=CropX2) ||
+ ((xx==Crop.x-1 || xx==CropX2) && yy>=Crop.y-1 && yy<=CropY2) )
{
p8[0] = p8[1] = p8[2] = 255;
continue;
}
/* Shade the cropped out area */
- else if ( yy<CropY1 || yy>=CropY2 || xx<CropX1 || xx>=CropX2 ) {
+ else if ( yy<Crop.y || yy>=CropY2 || xx<Crop.x || xx>=CropX2 ) {
for (c=0; c<3; c++) p8[c] = p8[c]/4;
continue;
}
if (data->RenderMode==render_default) {
/* Shade out the alignment lines */
if ( CFG->drawLines &&
- yy > CropY1 + 1 && yy < CropY2 - 2 &&
- xx > CropX1 + 1 && xx < CropX2 - 2 ) {
- int dx = (xx - CropX1) * drawLines % CropWidth / drawLines;
- int dy = (yy - CropY1) * drawLines % CropHeight / drawLines;
+ yy > Crop.y + 1 && yy < CropY2 - 2 &&
+ xx > Crop.x + 1 && xx < CropX2 - 2 ) {
+ int dx = (xx-Crop.x) * drawLines % Crop.width / drawLines;
+ int dy = (yy-Crop.y) * drawLines % Crop.height / drawLines;
if (dx == 0 || dy == 0) {
p8[0] /= 2;
p8[1] /= 2;
@@ -665,10 +651,9 @@
static gboolean preview_draw_crop(preview_data *data)
{
- int CropX1, CropX2, CropY1, CropY2;
- scale_crop_to_final_image(data->UF, &CropX1, &CropX2, &CropY1, &CropY2);
- preview_draw_area(data, CropX1, CropY1, CropX2-CropX1, CropY2-CropY1);
-
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(data->UF, &Crop);
+ preview_draw_area(data, Crop.x, Crop.y, Crop.width, Crop.height);
return FALSE;
}
@@ -685,16 +670,16 @@
return TRUE;
if (!is_rendering(data)) {
/* Set the area to redraw based on the crop rectangle and view port. */
- int x1, x2, y1, y2;
- scale_crop_to_final_image(data->UF, &x1, &x2, &y1, &y2);
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(data->UF, &Crop);
GdkRectangle viewRect;
gtk_image_view_get_viewport(GTK_IMAGE_VIEW(data->PreviewWidget),
&viewRect);
- x1 = MAX(x1, viewRect.x);
- int width = MIN(MAX(x2 - x1, 0), viewRect.width);
- y1 = MAX(y1, viewRect.y);
- int height = MIN(MAX(y2 - y1, 0), viewRect.height);
+ int x1 = MAX(Crop.x, viewRect.x);
+ int width = MIN(Crop.width, viewRect.width);
+ int y1 = MAX(Crop.y, viewRect.y);
+ int height = MIN(Crop.height, viewRect.height);
data->OverUnderTicker++;
preview_draw_area(data, x1, y1, width, height);
@@ -1169,15 +1154,15 @@
ufraw_image_data *img = ufraw_get_image(data->UF,
ufraw_develop_phase, TRUE);
- int CropX1, CropX2, CropY1, CropY2;
- scale_crop_to_final_image(data->UF, &CropX1, &CropX2, &CropY1, &CropY2);
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(data->UF, &Crop);
double rgb[3];
guint64 sum[3], sqr[3];
int live_his[live_his_size][4];
memset(live_his, 0, sizeof(live_his));
- for (y=CropY1; y < CropY2; y++)
- for (x=CropX1; x < CropX2; x++) {
+ for (y=Crop.y; y < Crop.y+Crop.height; y++)
+ for (x=Crop.x; x < Crop.x+Crop.width; x++) {
guint8 *p8 = img->buffer + y*img->rowstride + x*img->depth;
for (c=0, max=0, min=0x100; c<3; c++) {
max = MAX(max, p8[c]);
@@ -1259,7 +1244,7 @@
}
gtk_widget_queue_draw(data->LiveHisto);
- int CropCount = (CropX2 - CropX1) * (CropY2 - CropY1);
+ int CropCount = Crop.width * Crop.height;
for (c=0; c<3; c++)
rgb[c] = sum[c]/CropCount;
color_labels_set(data->AvrLabels, rgb);
@@ -1746,7 +1731,8 @@
(GSourceFunc)(render_spot), data, NULL);
return TRUE;
}
- if ( data->PageNum==data->PageNumCrop ) {
+ if (data->PageNum==data->PageNumCrop ||
+ data->PageNum==data->PageNumLensfun) {
data->PreviewButtonPressed = TRUE;
return TRUE;
}
@@ -1869,7 +1855,8 @@
(void)user_data;
if (!gtk_event_box_get_above_child(GTK_EVENT_BOX(event_box)))
return FALSE;
- if ( data->PageNum==data->PageNumCrop )
+ if (data->PageNum==data->PageNumCrop ||
+ data->PageNum==data->PageNumLensfun)
return crop_motion_notify(data, event);
if ((event->state&GDK_BUTTON1_MASK)==0) return FALSE;
if ( !data->PreviewButtonPressed ) return FALSE;
@@ -1951,38 +1938,40 @@
data->FreezeDialog--;
- int CropX1, CropX2, CropY1, CropY2;
- scale_crop_to_final_image(data->UF, &CropX1, &CropX2, &CropY1, &CropY2);
+ UFRectangle Crop;
+ ufraw_get_scaled_crop(data->UF, &Crop);
+ int CropX2 = Crop.x + Crop.width;
+ int CropY2 = Crop.y + Crop.height;
int x1[4], x2[4], y1[4], y2[4], i = 0;
- if (CropX1!=data->DrawnCropX1) {
- x1[i] = MIN(CropX1, data->DrawnCropX1);
- x2[i] = MAX(CropX1, data->DrawnCropX1);
- y1[i] = MIN(CropY1, data->DrawnCropY1);
+ if (Crop.x!=data->DrawnCropX1) {
+ x1[i] = MIN(Crop.x, data->DrawnCropX1);
+ x2[i] = MAX(Crop.x, data->DrawnCropX1);
+ y1[i] = MIN(Crop.y, data->DrawnCropY1);
y2[i] = MAX(CropY2, data->DrawnCropY2);
- data->DrawnCropX1 = CropX1;
+ data->DrawnCropX1 = Crop.x;
i++;
}
if (CropX2!=data->DrawnCropX2) {
x1[i] = MIN(CropX2, data->DrawnCropX2);
x2[i] = MAX(CropX2, data->DrawnCropX2);
- y1[i] = MIN(CropY1, data->DrawnCropY1);
+ y1[i] = MIN(Crop.y, data->DrawnCropY1);
y2[i] = MAX(CropY2, data->DrawnCropY2);
data->DrawnCropX2 = CropX2;
i++;
}
- if (CropY1!=data->DrawnCropY1) {
- y1[i] = MIN(CropY1, data->DrawnCropY1);
- y2[i] = MAX(CropY1, data->DrawnCropY1);
- x1[i] = MIN(CropX1, data->DrawnCropX1);
+ if (Crop.y!=data->DrawnCropY1) {
+ y1[i] = MIN(Crop.y, data->DrawnCropY1);
+ y2[i] = MAX(Crop.y, data->DrawnCropY1);
+ x1[i] = MIN(Crop.x, data->DrawnCropX1);
x2[i] = MAX(CropX2, data->DrawnCropX2);
- data->DrawnCropY1 = CropY1;
+ data->DrawnCropY1 = Crop.y;
i++;
}
if (CropY2!=data->DrawnCropY2) {
y1[i] = MIN(CropY2, data->DrawnCropY2);
y2[i] = MAX(CropY2, data->DrawnCropY2);
- x1[i] = MIN(CropX1, data->DrawnCropX1);
+ x1[i] = MIN(Crop.x, data->DrawnCropX1);
x2[i] = MAX(CropX2, data->DrawnCropX2);
data->DrawnCropY2 = CropY2;
i++;
@@ -2970,39 +2959,14 @@
* are valid. Try to preserve them over a rotate forth and back and try to
* preserve their geometry.
*/
-static void adjustment_update_rotation(GtkAdjustment *adj, gpointer user_data)
+void resize_canvas(preview_data *data)
{
- preview_data *data = get_preview_data(adj);
- (void)user_data;
-
- /* Normalize the "unnormalized" value displayed to the user to
- * -180 < a <= 180, though we later normalize to an orientation
- * and flip plus 0 <= a < 90 rotation for processing. */
- if (data->FreezeDialog)
- return;
-
gboolean FullCrop =
CFG->CropX1==0 && CFG->CropX2==data->UF->rotatedWidth &&
CFG->CropY1==0 && CFG->CropY2==data->UF->rotatedHeight;
- int oldFlip = CFG->orientation;
- ufraw_unnormalize_rotation(data->UF);
- CFG->rotationAngle = gtk_adjustment_get_value(data->RotationAdjustment);
- CFG->orientation = data->UnnormalizedOrientation;
- ufraw_normalize_rotation(data->UF);
- int newFlip = CFG->orientation;
- int flip;
- for (flip=0; flip<8; flip++) {
- CFG->orientation = oldFlip;
- ufraw_flip_orientation(data->UF, flip);
- if (CFG->orientation == newFlip)
- break;
- }
- CFG->orientation = oldFlip;
- ufraw_flip_image(data->UF, flip);
- gtk_widget_set_sensitive(data->ResetRotationAdjustment,
- CFG->rotationAngle != 0 ||
- CFG->orientation != CFG->CameraOrientation);
+
ufraw_get_image_dimensions(data->UF);
+
if (FullCrop) {
if (CFG->LockAspect) {
double newAspect = (double)data->UF->rotatedWidth /
@@ -3046,15 +3010,47 @@
data->SpotY1 = -1;
data->SpotY2 = -1;
}
- ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
-
if (CFG->CropX2 > data->UF->rotatedWidth)
fix_crop_aspect(data, top_right_cursor, FALSE);
else if (CFG->CropY2 > data->UF->rotatedHeight)
fix_crop_aspect(data, bottom_left_cursor, FALSE);
else
update_crop_ranges(data, FALSE);
- update_scales(data);
+}
+
+static void adjustment_update_rotation(GtkAdjustment *adj, gpointer user_data)
+{
+ preview_data *data = get_preview_data(adj);
+ (void)user_data;
+
+ /* Normalize the "unnormalized" value displayed to the user to
+ * -180 < a <= 180, though we later normalize to an orientation
+ * and flip plus 0 <= a < 90 rotation for processing. */
+ if (data->FreezeDialog)
+ return;
+
+ int oldFlip = CFG->orientation;
+ ufraw_unnormalize_rotation(data->UF);
+ CFG->rotationAngle = gtk_adjustment_get_value(data->RotationAdjustment);
+ CFG->orientation = data->UnnormalizedOrientation;
+ ufraw_normalize_rotation(data->UF);
+ int newFlip = CFG->orientation;
+ int flip;
+ for (flip=0; flip<8; flip++) {
+ CFG->orientation = oldFlip;
+ ufraw_flip_orientation(data->UF, flip);
+ if (CFG->orientation == newFlip)
+ break;
+ }
+ CFG->orientation = oldFlip;
+ ufraw_flip_image(data->UF, flip);
+ gtk_widget_set_sensitive(data->ResetRotationAdjustment,
+ CFG->rotationAngle != 0 ||
+ CFG->orientation != CFG->CameraOrientation);
+
+ ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
+ resize_canvas(data);
+ render_preview(data);
}
void ufraw_image_changed(UFObject *obj, UFEventType type)
@@ -3954,7 +3950,8 @@
gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box), TRUE);
gdk_window_set_cursor(event_box->window, data->Cursor[spot_cursor]);
draw_spot(data, TRUE);
- } else if ( page_num==data->PageNumCrop ) {
+ } else if ( page_num==data->PageNumCrop ||
+ page_num==data->PageNumLensfun) {
gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box), TRUE);
gdk_window_set_cursor(event_box->window, data->Cursor[crop_cursor]);
draw_spot(data, FALSE);
@@ -5458,7 +5455,10 @@
#ifdef HAVE_LENSFUN
/* Lens correction page */
page = notebook_page_new(notebook, _("Lens correction"), "lens");
+ data->PageNumLensfun = gtk_notebook_page_num(notebook, page);
lens_fill_interface(data, page);
+#else /* HAVE_LENSFUN */
+ data->PageNumLensfun = -1;
#endif /* HAVE_LENSFUN */
page = notebook_page_new(notebook, _("Base curve"), "base-curve");
@@ -5656,6 +5656,7 @@
while (gtk_events_pending()) gtk_main_iteration();
#endif
if ( CFG->WindowMaximized ) {
+ gtk_widget_set_size_request(scroll, -1, -1);
preview_progress_disable(data);
while (gtk_events_pending()) gtk_main_iteration();
// scroll widget is allocated size only after gtk_widget_show_all()
@@ -5701,6 +5702,7 @@
} else {
CFG->size = 0;
}
+ ufraw_invalidate_layer(data->UF, ufraw_first_phase);
/* Save initial WB data for the sake of "Reset WB" */
UFObject *Image = CFG->ufobject;
Index: ufraw.h
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw.h,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -d -r1.145 -r1.146
--- ufraw.h 30 Jan 2010 00:48:52 -0000 1.145
+++ ufraw.h 5 Feb 2010 23:22:15 -0000 1.146
@@ -380,6 +380,8 @@
void ufraw_normalize_rotation(ufraw_data *uf);
void ufraw_unnormalize_rotation(ufraw_data *uf);
void ufraw_get_image_dimensions(ufraw_data *uf);
+/* Get scaled crop coordinates in final image coordinates */
+void ufraw_get_scaled_crop(ufraw_data *uf, UFRectangle *crop);
UFRectangle ufraw_image_get_subarea_rectangle(ufraw_image_data *img,
unsigned saidx);
@@ -465,10 +467,9 @@
/* prototype for functions in ufraw_writer.c */
int ufraw_write_image(ufraw_data *uf);
void ufraw_write_image_data(
- ufraw_data *uf,
- void * volatile out,
- int width, int height, int left, int top, int bitDepth, int grayscaleMode,
- int (*row_writer) (ufraw_data *, void * volatile, void *, int, int, int,
int, int));
+ ufraw_data *uf, void * volatile out,
+ const UFRectangle *Crop, int bitDepth, int grayscaleMode,
+ int (*row_writer)(ufraw_data *, void * volatile, void *, int, int, int,
int, int));
/* prototype for functions in ufraw_delete.c */
long ufraw_delete(void *widget, ufraw_data *uf);
Index: ufraw-gimp.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw-gimp.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- ufraw-gimp.c 23 Jan 2010 05:00:58 -0000 1.61
+++ ufraw-gimp.c 5 Feb 2010 23:22:15 -0000 1.62
@@ -309,7 +309,8 @@
GimpDrawable *drawable;
GimpPixelRgn pixel_region;
gint32 layer;
- int height, width, top, left, depth, tile_height, row, nrows;
+ UFRectangle Crop;
+ int depth, tile_height, row, nrows;
(void)widget;
uf->gimpImage = -1;
@@ -317,21 +318,15 @@
if (uf->conf->embeddedImage) {
if (ufraw_convert_embedded(uf)!=UFRAW_SUCCESS)
return UFRAW_ERROR;
- height = uf->thumb.height;
- width = uf->thumb.width;
- top = 0;
- left = 0;
+ Crop.height = uf->thumb.height;
+ Crop.width = uf->thumb.width;
+ Crop.y = 0;
+ Crop.x = 0;
depth = 3;
} else {
if (ufraw_convert_image(uf)!=UFRAW_SUCCESS)
return UFRAW_ERROR;
- ufraw_image_data *FirstImage = &uf->Images[ufraw_first_phase];
- height = (uf->conf->CropY2 - uf->conf->CropY1)
- * FirstImage->height / uf->rotatedHeight;
- width = (uf->conf->CropX2 - uf->conf->CropX1)
- * FirstImage->width / uf->rotatedWidth;
- top = uf->conf->CropY1 * FirstImage->height / uf->rotatedHeight;
- left = uf->conf->CropX1 * FirstImage->width / uf->rotatedWidth;
+ ufraw_get_scaled_crop(uf, &Crop);
#ifdef UFRAW_CINEPAINT
if ( uf->conf->profile[out_profile]
[uf->conf->profileIndex[out_profile]].BitDepth==16 )
@@ -342,7 +337,7 @@
depth = 3;
#endif
}
- uf->gimpImage = gimp_image_new(width, height,
+ uf->gimpImage = gimp_image_new(Crop.width, Crop.height,
depth==3 ? GIMP_RGB : U16_RGB );
if (uf->gimpImage== -1) {
ufraw_message(UFRAW_ERROR, _("Can't allocate new image."));
@@ -351,8 +346,8 @@
gimp_image_set_filename(uf->gimpImage, uf->filename);
/* Create the "background" layer to hold the image... */
- layer = gimp_layer_new(uf->gimpImage, _("Background"), width,
- height, depth==3 ? GIMP_RGB_IMAGE : U16_RGB_IMAGE,
+ layer = gimp_layer_new(uf->gimpImage, _("Background"), Crop.width,
+ Crop.height, depth==3 ? GIMP_RGB_IMAGE : U16_RGB_IMAGE,
100.0, GIMP_NORMAL_MODE);
gimp_image_add_layer(uf->gimpImage, layer, 0);
@@ -363,14 +358,14 @@
tile_height = gimp_tile_height();
if (uf->conf->embeddedImage) {
- for (row = 0; row < height; row += tile_height) {
- nrows = MIN(height-row, tile_height);
+ for (row = 0; row < Crop.height; row += tile_height) {
+ nrows = MIN(Crop.height-row, tile_height);
gimp_pixel_rgn_set_rect(&pixel_region,
- uf->thumb.buffer+3*row*width, 0, row, width, nrows);
+ uf->thumb.buffer+3*row*Crop.width, 0, row, Crop.width,
nrows);
}
} else {
- ufraw_write_image_data(uf, &pixel_region, width, height, left, top,
- depth==3 ? 8 : 16, 0, gimp_row_writer);
+ ufraw_write_image_data(uf, &pixel_region, &Crop, depth==3 ? 8 : 16, 0,
+ gimp_row_writer);
}
gimp_drawable_flush(drawable);
gimp_drawable_detach(drawable);
Index: ufraw_ufraw.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_ufraw.c,v
retrieving revision 1.233
retrieving revision 1.234
diff -u -d -r1.233 -r1.234
--- ufraw_ufraw.c 30 Jan 2010 00:48:52 -0000 1.233
+++ ufraw_ufraw.c 5 Feb 2010 23:22:16 -0000 1.234
@@ -47,7 +47,6 @@
static void ufraw_convert_image_first(ufraw_data *uf, UFRawPhase phase);
static void ufraw_convert_image_transform(ufraw_data *uf, ufraw_image_data
*img,
ufraw_image_data *outimg, UFRectangle *area);
-static void ufraw_prepare_transform(ufraw_data *uf);
static void ufraw_convert_prepare_first_buffer(ufraw_data *uf,
ufraw_image_data *img);
static void ufraw_convert_prepare_transform_buffer(ufraw_data *uf,
@@ -352,12 +351,7 @@
dcraw_image_dimensions(uf->raw, uf->conf->orientation, 1,
&uf->initialHeight, &uf->initialWidth);
- // update rotated dimensions
- double rotationRadians = (uf->conf->rotationAngle * 2 * M_PI) / 360;
- uf->rotatedWidth = ceil((uf->initialHeight * sin(rotationRadians))
- + (uf->initialWidth * cos(rotationRadians)));
- uf->rotatedHeight = ceil((uf->initialWidth * sin(rotationRadians))
- + (uf->initialHeight * cos(rotationRadians)));
+ ufraw_get_image(uf, ufraw_transform_phase, FALSE);
if (uf->conf->CropX1 < 0) uf->conf->CropX1 = 0;
if (uf->conf->CropY1 < 0) uf->conf->CropY1 = 0;
@@ -365,6 +359,21 @@
if (uf->conf->CropY2 < 0) uf->conf->CropY2 = uf->rotatedHeight;
}
+/* Get scaled crop coordinates in final image coordinates */
+void ufraw_get_scaled_crop(ufraw_data *uf, UFRectangle *crop)
+{
+ ufraw_image_data *img = ufraw_get_image(uf, ufraw_transform_phase, FALSE);
+
+ float scale_x = ((float)img->width) / uf->rotatedWidth;
+ float scale_y = ((float)img->height) / uf->rotatedHeight;
+ crop->x = MAX(floor(uf->conf->CropX1 * scale_x), 0);
+ int x2 = MIN(ceil(uf->conf->CropX2 * scale_x), img->width);
+ crop->width = x2 - crop->x;
+ crop->y = MAX(floor(uf->conf->CropY1 * scale_y), 0);
+ int y2 = MIN(ceil(uf->conf->CropY2 * scale_y), img->height);
+ crop->height = y2 - crop->y;
+}
+
int ufraw_config(ufraw_data *uf, conf_data *rc, conf_data *conf, conf_data
*cmd)
{
int status;
@@ -768,14 +777,14 @@
ufraw_convert_image_first(uf, ufraw_first_phase);
UFRectangle area = { 0, 0, img->width, img->height };
+ // prepare_transform has to be called before applying vignetting
+ ufraw_image_data *img2 = &uf->Images[ufraw_transform_phase];
+ ufraw_convert_prepare_transform_buffer(uf, img2, img->width, img->height);
#ifdef HAVE_LENSFUN
- ufraw_prepare_transform(uf);
if (uf->modifier != NULL) {
ufraw_convert_image_vignetting(uf, img, &area);
}
#endif
- ufraw_image_data *img2 = &uf->Images[ufraw_transform_phase];
- ufraw_convert_prepare_transform_buffer(uf, img2, img->width, img->height);
if (img2->buffer != NULL) {
area.width = img2->width;
area.height = img2->height;
@@ -808,15 +817,23 @@
float sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360);
float cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360);
- int x, y, c;
-
+ // If we rotate around the center:
+ // srcX = (X-outimg->width/2)*cosine + (Y-outimg->height/2)*sine;
+ // srcY = -(X-outimg->width/2)*sine + (Y-outimg->height/2)*cosine;
+ // Then the base offset is:
+ // baseX = img->width/2;
+ // baseY = img->height/2;
+ // Since we rotate around the top-left corner, the base offset is:
+ float baseX = img->width/2 - outimg->width/2*cosine -
outimg->height/2*sine;
+ float baseY = img->height/2 + outimg->width/2*sine -
outimg->height/2*cosine;
#ifdef HAVE_LENSFUN
gboolean applyLF = uf->modifier != NULL && (uf->modFlags &
UF_LF_TRANSFORM);
#endif
+ int x, y, c;
for (y = area->y; y < area->y + area->height; y++) {
guint8 *cur0 = outimg->buffer + y * outimg->rowstride;
- float srcX0 = y*sine - img->height*sine*cosine;
- float srcY0 = y*cosine + img->height*sine*sine;
+ float srcX0 = y*sine + baseX;
+ float srcY0 = y*cosine + baseY;
for (x = area->x; x < area->x + area->width; x++) {
guint16 *cur = (guint16 *)(cur0 + x * outimg->depth);
float srcX = srcX0 + x*cosine;
@@ -1365,10 +1382,46 @@
}
}
+static void ufraw_convert_prepare_transform(ufraw_data *uf,
+ int width, int height, gboolean reverse)
+{
+#ifdef HAVE_LENSFUN
+ conf_data *conf = uf->conf;
+ if (uf->modifier != NULL)
+ lf_modifier_destroy(uf->modifier);
+ uf->modifier = NULL;
+
+ if (conf->camera == NULL || conf->lens == NULL)
+ return;
+
+ uf->modifier = lf_modifier_new(conf->lens, conf->camera->CropFactor,
+ width, height);
+ if (uf->modifier == NULL)
+ return;
+
+ float real_scale = pow(2.0, conf->lens_scale);
+ uf->modFlags = lf_modifier_initialize(uf->modifier, conf->lens,
+ LF_PF_U16, conf->focal_len, conf->aperture, conf->subject_distance,
+ real_scale, conf->cur_lens_type,
+ UF_LF_TRANSFORM | LF_MODIFY_VIGNETTING, reverse);
+ if ((uf->modFlags & UF_LF_ALL) == 0) {
+ lf_modifier_destroy(uf->modifier);
+ uf->modifier = NULL;
+ }
+#else /* HAVE_LENSFUN */
+ (void)uf;
+ (void)width;
+ (void)height;
+ (void)reverse;
+#endif /* HAVE_LENSFUN */
+}
+
static void ufraw_convert_prepare_transform_buffer(ufraw_data *uf,
ufraw_image_data *img, int width, int height)
{
- ufraw_prepare_transform(uf);
+ const int iWidth = uf->initialWidth;
+ const int iHeight = uf->initialHeight;
+ ufraw_convert_prepare_transform(uf, iWidth, iHeight, TRUE);
#ifdef HAVE_LENSFUN
if (uf->conf->rotationAngle == 0 &&
(uf->modifier == NULL || !(uf->modFlags & UF_LF_TRANSFORM)))
@@ -1380,15 +1433,55 @@
img->buffer = NULL;
img->width = width;
img->height = height;
- } else {
- double sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360);
- double cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360);
- int newWidth = ceil((height * sine) + (width * cosine));
- int newHeight = ceil((width * sine) + (height * cosine));
- width = newWidth;
- height = newHeight;
- ufraw_image_init(img, width, height, 8);
+ // We still need the transform for vignetting
+ ufraw_convert_prepare_transform(uf, width, height, FALSE);
+ uf->rotatedWidth = iWidth;
+ uf->rotatedHeight = iHeight;
+ return;
}
+ const float sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360);
+ const float cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360);
+ const float midX = iWidth/2.0 - 0.5;
+ const float midY = iHeight/2.0 - 0.5;
+#ifdef HAVE_LENSFUN
+ gboolean applyLF = uf->modifier != NULL && (uf->modFlags &
UF_LF_TRANSFORM);
+#endif
+ float maxX = 0, maxY = 0;
+ int i;
+ for (i = 0; i < iWidth + iHeight - 1; i++) {
+ int x, y;
+ if (i < iWidth) { // Trace the left border of the image
+ x = i;
+ y = 0;
+ } else { // Trace the bottom border of the image
+ x = iWidth - 1;
+ y = i - iWidth + 1;
+ }
+ float buff[2];
+#ifdef HAVE_LENSFUN
+ if (applyLF) {
+ lf_modifier_apply_geometry_distortion(uf->modifier,
+ x, y, 1, 1, buff);
+ } else {
+ buff[0] = x;
+ buff[1] = y;
+ }
+#else
+ buff[0] = x;
+ buff[1] = y;
+#endif
+ float srcX = (buff[0]-midX)*cosine - (buff[1]-midY)*sine;
+ float srcY = (buff[0]-midX)*sine + (buff[1]-midY)*cosine;
+ maxX = MAX(maxX, fabs(srcX));
+ maxY = MAX(maxY, fabs(srcY));
+ }
+ // Do not allow increasing canvas size by more than a factor of 2
+ uf->rotatedWidth = MIN(ceil(2*maxX), 2*iWidth);
+ uf->rotatedHeight = MIN(ceil(2*maxY), 2*iHeight);
+ int newWidth = uf->rotatedWidth * width / iWidth;
+ int newHeight = uf->rotatedHeight * height / iHeight;
+ ufraw_image_init(img, newWidth, newHeight, 8);
+ ufraw_convert_prepare_transform(uf, width, height, FALSE);
}
/*
@@ -1463,38 +1556,6 @@
}
#endif
-static void ufraw_prepare_transform(ufraw_data *uf)
-{
-#ifdef HAVE_LENSFUN
- ufraw_image_data *img = &uf->Images[ufraw_first_phase];
- conf_data *conf = uf->conf;
-
- if (uf->modifier != NULL)
- lf_modifier_destroy(uf->modifier);
- uf->modifier = NULL;
-
- if (conf->camera == NULL || conf->lens == NULL)
- return;
-
- uf->modifier = lf_modifier_new(conf->lens, conf->camera->CropFactor,
- img->width, img->height);
- if (uf->modifier == NULL)
- return;
-
- float real_scale = pow(2.0, conf->lens_scale);
- uf->modFlags = lf_modifier_initialize(uf->modifier, conf->lens,
- LF_PF_U16, conf->focal_len, conf->aperture, conf->subject_distance,
- real_scale, conf->cur_lens_type,
- UF_LF_TRANSFORM | LF_MODIFY_VIGNETTING, FALSE);
- if ((uf->modFlags & UF_LF_ALL) == 0) {
- lf_modifier_destroy(uf->modifier);
- uf->modifier = NULL;
- }
-#else /* HAVE_LENSFUN */
- (void)uf;
-#endif /* HAVE_LENSFUN */
-}
-
/*
* This function is very permissive in accepting NULL pointers but it does
* so to make it easy to call this function: consider it documentation with
Index: ufraw_ui.h
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_ui.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- ufraw_ui.h 31 Jan 2010 08:23:27 -0000 1.34
+++ ufraw_ui.h 5 Feb 2010 23:22:16 -0000 1.35
@@ -162,6 +162,7 @@
int PageNum;
int PageNumSpot;
int PageNumGray;
+ int PageNumLensfun;
int PageNumLightness;
int PageNumCrop;
int HisMinHeight;
@@ -195,6 +196,8 @@
preview_data *get_preview_data (void *object);
+void resize_canvas(preview_data *data);
+
void lens_fill_interface (preview_data *data, GtkWidget *page);
GtkWidget *table_with_frame (GtkWidget *box, char *label, gboolean expand);
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
ufraw-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ufraw-cvs