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
ufraw-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ufraw-cvs

Reply via email to