#include "config.h" #include #include #ifdef __GNUC__ #warning GTK_DISABLE_DEPRECATED #endif #undef GTK_DISABLE_DEPRECATED #include #include #include "fp.h" extern FP_Params Current; extern GimpDrawable *drawable, *mask; extern ReducedImage *reduced; extern gint nudgeArray[256]; gint colorSign[3][ALL_PRIMARY]= {{1,-1,-1,-1,1,1},{-1,1,-1,1,1,-1},{-1,-1,1,1,-1,1}}; void initializeFilterPacks() { gint i, j; for (i=0; i<256; i++) for (j=BY_HUE; jbpp; ReducedImage *temp = (ReducedImage *) malloc (sizeof (ReducedImage)); guchar *tempRGB, *src_row, *tempmask, *src_mask_row, R, G, B; gint i, j, whichcol, whichrow, x1, x2, y1, y2; GimpPixelRgn srcPR, srcMask; gboolean NoSelectionMade=TRUE; gdouble *tempHSV; GimpRGB rgb; GimpHSV hsv; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = x2 - x1; height = y2 - y1; if (width != drawable->width && height != drawable->height) NoSelectionMade = FALSE; if (Slctn == 0) { x1 = 0; x2 = drawable->width; y1 = 0; y2 = drawable->height; } if (Slctn == 2) { x1 = MAX (0, x1 - width / 2.0); x2 = MIN (drawable->width, x2 + width / 2.0); y1 = MAX (0, y1 - height / 2.0); y2 = MIN (drawable->height, y2 + height / 2.0); } width = x2 - x1; height = y2 - y1; if (width > height) { RW = LongerSize; RH = (gfloat) height * (gfloat) LongerSize / (gfloat) width; } else { RH = LongerSize; RW = (gfloat) width * (gfloat) LongerSize / (gfloat) height; } tempRGB = (guchar *) malloc (RW * RH * bytes); tempHSV = (gdouble *) malloc (RW * RH * bytes * sizeof (gdouble)); tempmask = (guchar *) malloc (RW * RH); gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE); src_row = (guchar *) malloc (width * bytes); src_mask_row = (guchar *) malloc (width * bytes); for (i = 0; i < RH; i++) { whichrow = (gfloat) i * (gfloat) height / (gfloat) RH; gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1 + whichrow, width); gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1 + whichrow, width); for (j = 0; j < RW; j++) { whichcol = (gfloat) j * (gfloat) width / (gfloat) RW; if (NoSelectionMade) tempmask[i * RW + j] = 255; else tempmask[i * RW + j] = src_mask_row[whichcol]; R = src_row[whichcol * bytes + 0]; G = src_row[whichcol * bytes + 1]; B = src_row[whichcol * bytes + 2]; gimp_rgb_set_uchar (&rgb, R, G, B); gimp_rgb_to_hsv (&rgb, &hsv); tempRGB[i * RW * bytes + j * bytes + 0] = R; tempRGB[i * RW * bytes + j * bytes + 1] = G; tempRGB[i * RW * bytes + j * bytes + 2] = B; tempHSV[i * RW * bytes + j * bytes + 0] = hsv.h; tempHSV[i * RW * bytes + j * bytes + 1] = hsv.s; tempHSV[i * RW * bytes + j * bytes + 2] = hsv.v; if (bytes == 4) tempRGB[i * RW * bytes + j * bytes + 3] = src_row[whichcol * bytes + 3]; } } temp->width = RW; temp->height = RH; temp->rgb = tempRGB; temp->hsv = tempHSV; temp->mask = tempmask; return temp; } /*************************************************************/ /************** The Preview Function *************************/ void fp_render_preview(GtkWidget *preview, gint changewhat, gint changewhich) { guchar *a; gint Inten, bytes=drawable->bpp; gint i, j, k, nudge, M, m, middle,JudgeBy; float partial; gint RW=reduced->width; gint RH=reduced->height; gint backupP[3], P[3], tempSat[JUDGE_BY][256]; a =(guchar *) malloc(bytes*RW); if (changewhat==SATURATION) for (k=0; k<256; k++) { for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes + j*bytes + 0]; backupP[1] = P[1] = (int) reduced->rgb[i*RW*bytes + j*bytes + 1]; backupP[2] = P[2] = (int) reduced->rgb[i*RW*bytes + j*bytes + 2]; m = MIN(MIN(P[0],P[1]),P[2]); M = MAX(MAX(P[0],P[1]),P[2]); middle=(M+m)/2; for (k=0; k<3; k++) if (P[k]!=m && P[k]!=M) middle=P[k]; partial = reduced->mask[i*RW+j]/255.0; for (JudgeBy=BY_HUE; JudgeByhsv[i*RW*bytes + j*bytes + JudgeBy]*255.0; /*DO SATURATION FIRST*/ if (changewhat != NONEATALL) { if (M!=m) { for (k=0; k<3; k++) if (backupP[k] == M) P[k] = MAX(P[k]+partial*Current.satAdj[JudgeBy][Inten],middle); else if (backupP[k] == m) P[k] = MIN(P[k]-partial*Current.satAdj[JudgeBy][Inten],middle); } P[0] += partial*Current.redAdj[JudgeBy][Inten]; P[1] += partial*Current.greenAdj[JudgeBy][Inten]; P[2] += partial*Current.blueAdj[JudgeBy][Inten]; } } Inten = reduced->hsv[i*RW*bytes + j*bytes + Current.ValueBy]*255.0; nudge = partial*nudgeArray[(Inten+Current.Offset)%256]; switch (changewhat) { case HUE: P[0] += colorSign[RED][changewhich] * nudge; P[1] += colorSign[GREEN][changewhich] * nudge; P[2] += colorSign[BLUE][changewhich] * nudge; break; case SATURATION: for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes+j*bytes+3]/255.0; a[3*j+k]=transp*a[3*j+k]+(1-transp)*fp_fake_transparency(i,j); } } gtk_preview_draw_row( GTK_PREVIEW(preview),a,0,i,RW); } free(a); gtk_widget_queue_draw (preview); } void Update_Current_FP (gint changewhat, gint changewhich) { int i, nudge; for (i=0; i<256; i++) { fp_Create_Nudge(nudgeArray); nudge=nudgeArray[(i+Current.Offset)%256]; switch (changewhat) { case HUE: Current.redAdj[Current.ValueBy][i] += colorSign[RED][changewhich] * nudge; Current.greenAdj[Current.ValueBy][i] += colorSign[GREEN][changewhich] * nudge; Current.blueAdj[Current.ValueBy][i] += colorSign[BLUE][changewhich] * nudge; break; case SATURATION: Current.satAdj[Current.ValueBy][i] += changewhich*nudge; break; case VALUE: Current.redAdj[Current.ValueBy][i] += changewhich * nudge; Current.greenAdj[Current.ValueBy][i] += changewhich * nudge; Current.blueAdj[Current.ValueBy][i] += changewhich * nudge; break; default: break; } /* switch */ } /* for */ } void fp_create_smoothness_graph (GtkWidget *preview) { guchar data[256*3]; gint nArray[256]; int i, j, toBeBlack; fp_Create_Nudge(nArray); for (i=0; i0 ) return 64; else return 196; }