Update of /cvsroot/ufraw/ufraw In directory vz-cvs-3.sog:/tmp/cvs-serv7720 Modified Files: ufraw.h ufraw_conf.c ufraw_preview.c ufraw_ufraw.c ufraw_ui.h ufraw_writer.c Log Message: Fix various lensfun scale and crop problems. Add --auto-crop and --aspect-ratio command line options. Patches by Vladimir Nadvornik
Index: ufraw_writer.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_writer.c,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -r1.77 -r1.78 --- ufraw_writer.c 27 Aug 2011 09:05:47 -0000 1.77 +++ ufraw_writer.c 19 Nov 2011 05:30:48 -0000 1.78 @@ -254,6 +254,13 @@ } } if (uf->conf->createID == only_id) { + if (uf->conf->autoCrop && !uf->LoadingID) { + ufraw_get_image_dimensions(uf); + uf->conf->CropX1 = (uf->rotatedWidth - uf->autoCropWidth) / 2; + uf->conf->CropX2 = uf->conf->CropX1 + uf->autoCropWidth; + uf->conf->CropY1 = (uf->rotatedHeight - uf->autoCropHeight) / 2; + uf->conf->CropY2 = uf->conf->CropY1 + uf->autoCropHeight; + } int status = conf_save(uf->conf, confFilename, NULL); g_free(confFilename); return status; Index: ufraw_preview.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_preview.c,v retrieving revision 1.358 retrieving revision 1.359 diff -u -d -r1.358 -r1.359 --- ufraw_preview.c 6 Nov 2011 03:30:55 -0000 1.358 +++ ufraw_preview.c 19 Nov 2011 05:30:48 -0000 1.359 @@ -932,9 +932,9 @@ ufraw_invalidate_layer(data->UF, ufraw_transform_phase); ufraw_get_image_dimensions(data->UF); CFG->CropX1 = (data->UF->rotatedWidth - data->UF->autoCropWidth) / 2; - CFG->CropX2 = (data->UF->rotatedWidth + data->UF->autoCropWidth) / 2; + CFG->CropX2 = CFG->CropX1 + data->UF->autoCropWidth; CFG->CropY1 = (data->UF->rotatedHeight - data->UF->autoCropHeight) / 2; - CFG->CropY2 = (data->UF->rotatedHeight + data->UF->autoCropHeight) / 2; + CFG->CropY2 = CFG->CropY1 + data->UF->autoCropHeight; update_crop_ranges(data, FALSE); CFG->autoCrop = enabled_state; } @@ -1578,9 +1578,17 @@ static void auto_button_toggle(GtkToggleButton *button, gboolean *valuep) { if (gtk_toggle_button_get_active(button)) { + /* the button is inactive most of the time, + clicking on it activates it, but + we immediately deactivate it here + so this function is called again recursively + via callback from gtk_toggle_button_set_active */ *valuep = !*valuep; gtk_toggle_button_set_active(button, FALSE); } + /* if this function is called directly, + the condition above is false and we only + update the button image */ if (*valuep) gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock( "object-automatic", GTK_ICON_SIZE_BUTTON)); @@ -2071,8 +2079,8 @@ CFG->CropY1 = 0; CFG->CropX2 = data->UF->rotatedWidth; CFG->CropY2 = data->UF->rotatedHeight; - data->AspectRatio = ((float)data->UF->rotatedWidth) / - data->UF->rotatedHeight; + CFG->aspectRatio = ((float)data->UF->rotatedWidth) / + data->UF->rotatedHeight; refresh_aspect(data); set_new_aspect(data); @@ -2221,20 +2229,17 @@ static void refresh_aspect(preview_data *data) { - int dy = CFG->CropY2 - CFG->CropY1; - data->AspectRatio = dy ? ((CFG->CropX2 - CFG->CropX1) / (float)dy) : 1.0; - // Look through a predefined list of aspect ratios size_t i; for (i = 0; i < sizeof(predef_aspects) / sizeof(predef_aspects[0]); i++) - if (data->AspectRatio >= predef_aspects[i].val * 0.999 && - data->AspectRatio <= predef_aspects[i].val * 1.001) { + if (CFG->aspectRatio >= predef_aspects[i].val * 0.999 && + CFG->aspectRatio <= predef_aspects[i].val * 1.001) { data->FreezeDialog++; gtk_entry_set_text(data->AspectEntry, predef_aspects[i].text); data->FreezeDialog--; return; } - char *text = g_strdup_printf("%.4g", data->AspectRatio); + char *text = g_strdup_printf("%.4g", CFG->aspectRatio); data->FreezeDialog++; gtk_entry_set_text(data->AspectEntry, text); data->FreezeDialog--; @@ -2262,13 +2267,16 @@ if (!CFG->LockAspect) { update_crop_ranges(data, render); + + int dy = CFG->CropY2 - CFG->CropY1; + CFG->aspectRatio = dy ? ((CFG->CropX2 - CFG->CropX1) / (float)dy) : 1.0; refresh_aspect(data); return; } - if (data->AspectRatio == 0) + if (CFG->aspectRatio == 0) aspect = ((double)data->UF->rotatedWidth) / data->UF->rotatedHeight; else - aspect = data->AspectRatio; + aspect = CFG->aspectRatio; switch (cursor) { case left_cursor: @@ -2391,27 +2399,27 @@ */ dx = CFG->CropX2 - cx; dy = CFG->CropY2 - cy; - if (dx / dy > data->AspectRatio) - dy = dx / data->AspectRatio; + if (dx / dy > CFG->aspectRatio) + dy = dx / CFG->aspectRatio; else - dx = dy * data->AspectRatio; + dx = dy * CFG->aspectRatio; if (dx > cx) { dx = cx; - dy = dx / data->AspectRatio; + dy = dx / CFG->aspectRatio; } if (cx + dx > data->UF->rotatedWidth) { dx = data->UF->rotatedWidth - cx; - dy = dx / data->AspectRatio; + dy = dx / CFG->aspectRatio; } if (dy > cy) { dy = cy; - dx = dy * data->AspectRatio; + dx = dy * CFG->aspectRatio; } if (cy + dy > data->UF->rotatedHeight) { dy = data->UF->rotatedHeight - cy; - dx = dy * data->AspectRatio; + dx = dy * CFG->aspectRatio; } CFG->CropX1 = floor(cx - dx + 0.5); @@ -2456,7 +2464,7 @@ sscanf(text, "%g", &aspect); } if (aspect >= 0.1 && aspect <= 10.0) - data->AspectRatio = aspect; + CFG->aspectRatio = aspect; } set_new_aspect(data); CFG->LockAspect = TRUE; @@ -2959,14 +2967,16 @@ if ((int *)valuep == &CFG->CropX1 || (int *)valuep == &CFG->CropX2 || (int *)valuep == &CFG->CropY1 || (int *)valuep == &CFG->CropY2) { - *((int *)valuep) = (int) gtk_adjustment_get_value(adj); - CursorType cursor = left_cursor; - if ((int *)valuep == &CFG->CropX1) cursor = left_cursor; - if ((int *)valuep == &CFG->CropX2) cursor = right_cursor; - if ((int *)valuep == &CFG->CropY1) cursor = top_cursor; - if ((int *)valuep == &CFG->CropY2) cursor = bottom_cursor; - fix_crop_aspect(data, cursor, TRUE); + /* values set by update_crop_ranges are ok and + do not have to be fixed */ if (!data->FreezeDialog) { + *((int *)valuep) = (int) gtk_adjustment_get_value(adj); + CursorType cursor = left_cursor; + if ((int *)valuep == &CFG->CropX1) cursor = left_cursor; + if ((int *)valuep == &CFG->CropX2) cursor = right_cursor; + if ((int *)valuep == &CFG->CropY1) cursor = top_cursor; + if ((int *)valuep == &CFG->CropY2) cursor = bottom_cursor; + fix_crop_aspect(data, cursor, TRUE); CFG->autoCrop = disabled_state; auto_button_toggle(data->AutoCropButton, &CFG->autoCrop); } @@ -3056,9 +3066,10 @@ double newAspect = (double)data->UF->rotatedWidth / data->UF->rotatedHeight; // Allow 1/aspect switch even if aspect is locked. - if (fabs(data->AspectRatio - 1 / newAspect) < 0.0001) { + if (fabs(CFG->aspectRatio - 1 / newAspect) < 0.0001) { CFG->CropX2 = data->UF->rotatedWidth; CFG->CropY2 = data->UF->rotatedHeight; + CFG->aspectRatio = newAspect; refresh_aspect(data); } } else { // Keep full crop @@ -5002,13 +5013,12 @@ gtk_widget_set_tooltip_text(GTK_WIDGET(data->AutoCropButton), _("Auto fit crop area")); auto_button_toggle(data->AutoCropButton, &CFG->autoCrop); - gtk_toggle_button_set_active(data->AutoCropButton, CFG->autoCrop); g_signal_connect(G_OBJECT(data->AutoCropButton), "toggled", G_CALLBACK(auto_button_toggled), &CFG->autoCrop); // Crop reset button: button = reset_button( - _("Reset the crop region"), G_CALLBACK(crop_reset), NULL); + _("Reset the crop area"), G_CALLBACK(crop_reset), NULL); gtk_table_attach(table, button, 5, 6, 1, 2, 0, 0, 0, 0); /* Aspect ratio controls */ @@ -5045,6 +5055,12 @@ lock_aspect(data->LockAspectButton, &CFG->LockAspect); /* Get initial aspect ratio */ + if (CFG->aspectRatio != 0.0) + set_new_aspect(data); + else { + int dy = CFG->CropY2 - CFG->CropY1; + CFG->aspectRatio = dy ? ((CFG->CropX2 - CFG->CropX1) / (float)dy) : 1.0; + } refresh_aspect(data); /* Size/shrink controls */ @@ -5433,7 +5449,6 @@ data->DrawnCropY1 = 0; data->DrawnCropY2 = 99999; - data->AspectRatio = 0.0; data->BlinkTimer = 0; data->DrawCropID = 0; for (i = 0; i < num_buttons; i++) { Index: ufraw.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw.h,v retrieving revision 1.164 retrieving revision 1.165 diff -u -d -r1.164 -r1.165 --- ufraw.h 6 Nov 2011 03:30:55 -0000 1.164 +++ ufraw.h 19 Nov 2011 05:30:48 -0000 1.165 @@ -252,6 +252,7 @@ char darkframeFile[max_path]; struct ufraw_struct *darkframe; int CropX1, CropY1, CropX2, CropY2; + double aspectRatio; int orientation; double rotationAngle; int lightnessAdjustmentCount; Index: ufraw_conf.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_conf.c,v retrieving revision 1.180 retrieving revision 1.181 diff -u -d -r1.180 -r1.181 --- ufraw_conf.c 4 Sep 2011 03:14:04 -0000 1.180 +++ ufraw_conf.c 19 Nov 2011 05:30:48 -0000 1.181 @@ -89,6 +89,7 @@ ahd_interpolation, 0, /* interpolation, smoothing */ "", NULL, /* darkframeFile, darkframe */ -1, -1, -1, -1, /* Crop X1,Y1,X2,Y2 */ + 0.0, /* aspectRatio */ -1, /* orientation */ 0, /* rotationAngle */ 0, /* lightness adjustment count */ @@ -746,6 +747,7 @@ if (!strcmp("Orientation", element)) sscanf(temp, "%d", &c->orientation); if (!strcmp("Crop", element)) sscanf(temp, "%d %d %d %d", &c->CropX1, &c->CropY1, &c->CropX2, &c->CropY2); + if (!strcmp("AspectRatio", element)) sscanf(temp, "%lf", &c->aspectRatio); if (!strcmp("Rotation", element)) sscanf(temp, "%lf", &c->rotationAngle); if (!strcmp("Shrink", element)) sscanf(temp, "%d", &c->shrink); if (!strcmp("Size", element)) sscanf(temp, "%d", &c->size); @@ -1259,6 +1261,8 @@ c->exifSource); buf = uf_markup_buf(buf, "<Crop>%d %d %d %d</Crop>\n", c->CropX1, c->CropY1, c->CropX2, c->CropY2); + if (c->aspectRatio != 0.0) + buf = uf_markup_buf(buf, "<AspectRatio>%lf</AspectRatio>\n", c->aspectRatio); buf = uf_markup_buf(buf, "<Rotation>%lf</Rotation>\n", c->rotationAngle); char *log = ufraw_message(UFRAW_GET_LOG, NULL); if (log != NULL) { @@ -1431,6 +1435,7 @@ dst->CropY1 = src->CropY1; dst->CropX2 = src->CropX2; dst->CropY2 = src->CropY2; + dst->aspectRatio = src->aspectRatio; dst->rotationAngle = src->rotationAngle; } @@ -1474,6 +1479,7 @@ if (cmd->embeddedImage != -1) conf->embeddedImage = cmd->embeddedImage; if (cmd->rotate != -1) conf->rotate = cmd->rotate; if (cmd->rotationAngle != NULLF) conf->rotationAngle = cmd->rotationAngle; + if (cmd->autoCrop != -1) conf->autoCrop = cmd->autoCrop; if (cmd->CropX1 != -1 || cmd->CropX2 != -1 || cmd->CropY1 != -1 || cmd->CropY2 != -1) conf->autoCrop = disabled_state; @@ -1481,6 +1487,7 @@ if (cmd->CropY1 != -1) conf->CropY1 = cmd->CropY1; if (cmd->CropX2 != -1) conf->CropX2 = cmd->CropX2; if (cmd->CropY2 != -1) conf->CropY2 = cmd->CropY2; + if (cmd->aspectRatio != 0.0) conf->aspectRatio = cmd->aspectRatio; if (cmd->silent != -1) conf->silent = cmd->silent; if (cmd->compression != NULLF) conf->compression = cmd->compression; if (cmd->autoExposure) { @@ -1655,6 +1662,8 @@ N_("--crop-(left|right|top|bottom)=PIXELS\n" " Crop the output to the given pixel range, relative to the\n" " raw image after rotation but before any scaling.\n"), + N_("--auto-crop Crop the output automatically.\n"), + N_("--aspect-ratio X:Y Set crop area aspect ratio.\n"), #ifdef HAVE_LENSFUN N_("--lensfun=none|auto Do not apply lens correction or try to apply\n" " correction by auto-detecting the lens (default none).\n"), @@ -1781,6 +1790,7 @@ { "crop-top", 1, 0, '2'}, { "crop-right", 1, 0, '3'}, { "crop-bottom", 1, 0, '4'}, + { "aspect-ratio", 1, 0, 'P'}, /* Binary flags that don't have a value are here at the end */ { "zip", 0, 0, 'z'}, { "nozip", 0, 0, 'Z'}, @@ -1794,6 +1804,7 @@ { "help", 0, 0, 'h'}, { "version", 0, 0, 'v'}, { "batch", 0, 0, 'b'}, + { "auto-crop", 0, 0, '0'}, { 0, 0, 0, 0} }; UFObject *tmpImage = ufraw_image_new(); @@ -1818,7 +1829,8 @@ &outTypeName, &cmd->profile[1][0].BitDepth, &rotateName, &createIDName, &outPath, &output, &darkframeFile, &restoreName, &clipName, &conf, - &cmd->CropX1, &cmd->CropY1, &cmd->CropX2, &cmd->CropY2 + &cmd->CropX1, &cmd->CropY1, &cmd->CropX2, &cmd->CropY2, + &cmd->aspectRatio }; cmd->autoExposure = disabled_state; cmd->autoBlack = disabled_state; @@ -1847,6 +1859,8 @@ cmd->CropY1 = -1; cmd->CropX2 = -1; cmd->CropY2 = -1; + cmd->autoCrop = -1; + cmd->aspectRatio = 0.0; cmd->rotate = -1; cmd->smoothing = -1; @@ -1982,6 +1996,25 @@ ufraw_message(UFRAW_ERROR, _("--batch is obsolete. Use ufraw-batch instead.")); return -1; + case '0': + cmd->autoCrop = enabled_state; + break; + case 'P': { + double num = 0.0, denom = 1.0; + locale = uf_set_locale_C(); + if (sscanf(optarg, "%lf:%lf", &num, &denom) < 2 && + sscanf(optarg, "%lf/%lf", &num, &denom) < 2 && + sscanf(optarg, "%lf", &num) == 0) { + ufraw_message(UFRAW_ERROR, + _("'%s' is not a valid value for the --%s option."), + optarg, options[index].name); + uf_reset_locale(locale); + return -1; + } + *(double *)optPointer[index] = num / denom; + uf_reset_locale(locale); + } + break; case '?': /* invalid option. Warning printed by getopt() */ return -1; default: Index: ufraw_ufraw.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_ufraw.c,v retrieving revision 1.268 retrieving revision 1.269 diff -u -d -r1.268 -r1.269 --- ufraw_ufraw.c 6 Nov 2011 03:30:55 -0000 1.268 +++ ufraw_ufraw.c 19 Nov 2011 05:30:48 -0000 1.269 @@ -363,6 +363,35 @@ if (uf->conf->CropY1 < 0) uf->conf->CropY1 = 0; if (uf->conf->CropX2 < 0) uf->conf->CropX2 = uf->rotatedWidth; if (uf->conf->CropY2 < 0) uf->conf->CropY2 = uf->rotatedHeight; + + if (uf->conf->aspectRatio <= 0) { + if (uf->conf->autoCrop) + /* preserve the initial aspect ratio - this should be consistent + with ufraw_convert_prepare_transform */ + uf->conf->aspectRatio = ((double)uf->initialWidth) / uf->initialHeight; + else + /* full rotated image / manually entered crop */ + uf->conf->aspectRatio = ((double)uf->conf->CropX2 - uf->conf->CropX1) + / (uf->conf->CropY2 - uf->conf->CropY1); + } else { + /* given aspectRatio */ + int cropWidth = uf->conf->CropX2 - uf->conf->CropX1; + int cropHeight = uf->conf->CropY2 - uf->conf->CropY1; + + if (cropWidth != (int)(cropHeight * uf->conf->aspectRatio + 0.5)) { + /* aspectRatio does not match the crop area - shrink the area */ + + if ((double)cropWidth / cropHeight > uf->conf->aspectRatio) { + cropWidth = cropHeight * uf->conf->aspectRatio + 0.5; + uf->conf->CropX1 = (uf->conf->CropX1 + uf->conf->CropX2 - cropWidth) / 2; + uf->conf->CropX2 = uf->conf->CropX1 + cropWidth; + } else { + cropHeight = cropWidth / uf->conf->aspectRatio + 0.5; + uf->conf->CropY1 = (uf->conf->CropY1 + uf->conf->CropY2 - cropHeight) / 2; + uf->conf->CropY2 = uf->conf->CropY1 + cropHeight; + } + } + } } /* Get scaled crop coordinates in final image coordinates */ @@ -815,9 +844,9 @@ if (uf->conf->autoCrop && !uf->LoadingID) { ufraw_get_image_dimensions(uf); uf->conf->CropX1 = (uf->rotatedWidth - uf->autoCropWidth) / 2; - uf->conf->CropX2 = (uf->rotatedWidth + uf->autoCropWidth) / 2; + uf->conf->CropX2 = uf->conf->CropX1 + uf->autoCropWidth; uf->conf->CropY1 = (uf->rotatedHeight - uf->autoCropHeight) / 2; - uf->conf->CropY2 = (uf->rotatedHeight + uf->autoCropHeight) / 2; + uf->conf->CropY2 = uf->conf->CropY1 + uf->autoCropHeight; } return UFRAW_SUCCESS; } @@ -1393,6 +1422,12 @@ { const int iWidth = uf->initialWidth; const int iHeight = uf->initialHeight; + + double aspectRatio = uf->conf->aspectRatio; + + if (aspectRatio == 0) + aspectRatio = ((double)iWidth) / iHeight; + #ifdef HAVE_LENSFUN ufraw_convert_prepare_transform(uf, iWidth, iHeight, TRUE, 1.0); if (uf->conf->rotationAngle == 0 && @@ -1412,12 +1447,16 @@ uf->rotatedHeight = iHeight; uf->autoCropWidth = iWidth; uf->autoCropHeight = iHeight; + if ((double)uf->autoCropWidth / uf->autoCropHeight > aspectRatio) + uf->autoCropWidth = uf->autoCropHeight * aspectRatio + 0.5; + else + uf->autoCropHeight = uf->autoCropWidth / aspectRatio + 0.5; + return; } const double sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360); const double cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360); - const float aspectRatio = (float)(uf->conf->CropX2 - uf->conf->CropX1) / - (uf->conf->CropY2 - uf->conf->CropY1); + const float midX = iWidth / 2.0 - 0.5; const float midY = iHeight / 2.0 - 0.5; #ifdef HAVE_LENSFUN @@ -1464,14 +1503,17 @@ } float scale = sqrt((iWidth - 1) * (iHeight - 1) / area); // Do not allow increasing canvas size by more than a factor of 2 - uf->rotatedWidth = MIN(ceil(2 * maxX) * scale, 2 * iWidth); - uf->rotatedHeight = MIN(ceil(2 * maxY) * scale, 2 * iHeight); - if (minX / minY > aspectRatio) - minX = minY * aspectRatio; - else - minY = minX / aspectRatio; + uf->rotatedWidth = MIN(ceil(2 * maxX + 1.0) * scale, 2 * iWidth); + uf->rotatedHeight = MIN(ceil(2 * maxY + 1.0) * scale, 2 * iHeight); + uf->autoCropWidth = MIN(floor(2 * minX) * scale, 2 * iWidth); uf->autoCropHeight = MIN(floor(2 * minY) * scale, 2 * iHeight); + + if ((double)uf->autoCropWidth / uf->autoCropHeight > aspectRatio) + uf->autoCropWidth = uf->autoCropHeight * aspectRatio + 0.5; + else + uf->autoCropHeight = uf->autoCropWidth / aspectRatio + 0.5; + int newWidth = uf->rotatedWidth * width / iWidth; int newHeight = uf->rotatedHeight * height / iHeight; ufraw_image_init(img, newWidth, newHeight, 8); Index: ufraw_ui.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_ui.h,v retrieving revision 1.46 retrieving revision 1.47 diff -u -d -r1.46 -r1.47 --- ufraw_ui.h 20 Feb 2011 06:15:20 -0000 1.46 +++ ufraw_ui.h 19 Nov 2011 05:30:48 -0000 1.47 @@ -159,7 +159,6 @@ int HisMinHeight; int UnnormalizedOrientation; /* Original aspect ratio (0) or actual aspect ratio */ - float AspectRatio; /* The aspect ratio entry field */ GtkEntry *AspectEntry; /* Output base filename (without the path) */ ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-novd2d _______________________________________________ ufraw-cvs mailing list ufraw-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ufraw-cvs