void free_rotate (ppm_t *p, double amount) { int x, y; double nx, ny; ppm_t tmp = {0, 0, NULL}; double f = amount * G_PI * 2 / 360.0; int rowstride = p->width * 3; ppm_new (&tmp, p->width, p->height); for (y = 0; y < p->height; y++) { for (x = 0; x < p->width; x++) { double r, d; nx = fabs (x - p->width / 2.0); ny = fabs (y - p->height / 2.0); r = sqrt (nx * nx + ny * ny); d = atan2 ((y - p->height / 2.0), (x - p->width / 2.0)); nx = (p->width / 2.0 + cos (d - f) * r); ny = (p->height / 2.0 + sin (d - f) * r); get_rgb (p, nx, ny, tmp.col + y * rowstride + x * 3); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
static void updatesmpreviewprev (void) { gint x, y; static ppm_t nsbuffer; guchar black[3] = {0, 0, 0}; guchar gray[3] = {120, 120, 120}; if (! PPM_IS_INITED (&nsbuffer)) { ppm_new (&nsbuffer, OMWIDTH, OMHEIGHT); } fill (&nsbuffer, black); for (y = 6; y < OMHEIGHT-4; y += 10) { for (x = 6; x < OMWIDTH-4; x += 10) { gdouble siz = 5 * getsiz_from_gui (x / (double)OMWIDTH, y / (double)OMHEIGHT); ppm_drawline (&nsbuffer, x-siz, y-siz, x+siz, y-siz, gray); ppm_drawline (&nsbuffer, x+siz, y-siz, x+siz, y+siz, gray); ppm_drawline (&nsbuffer, x+siz, y+siz, x-siz, y+siz, gray); ppm_drawline (&nsbuffer, x-siz, y+siz, x-siz, y-siz, gray); } } gimp_preview_area_draw (GIMP_PREVIEW_AREA (smpreviewprev), 0, 0, OMWIDTH, OMHEIGHT, GIMP_RGB_IMAGE, nsbuffer.col, OMWIDTH * 3); }
void dummybrushdmenuselect (GtkWidget *w, gpointer data) { ppm_kill (&brushppm); ppm_new (&brushppm, 10,10); brush_from_file = 0; update_brush_preview (NULL); }
void ppm_pad (ppm_t *p, int left,int right, int top, int bottom, guchar *bg) { int x, y; ppm_t tmp = {0, 0, NULL}; ppm_new (&tmp, p->width + left + right, p->height + top + bottom); for (y = 0; y < tmp.height; y++) { guchar *row, *srcrow; row = tmp.col + y * tmp.width * 3; if ((y < top) || (y >= tmp.height-bottom)) { for (x = 0; x < tmp.width; x++) { int k = x * 3; row[k+0] = bg[0]; row[k+1] = bg[1]; row[k+2] = bg[2]; } continue; } srcrow = p->col + (y-top) * p->width * 3; for (x = 0; x < left; x++) { int k = x * 3; row[k+0] = bg[0]; row[k+1] = bg[1]; row[k+2] = bg[2]; } for (; x < tmp.width-right; x++) { int k = y * tmp.width * 3 + x * 3; tmp.col[k+0] = srcrow[(x - left) * 3 + 0]; tmp.col[k+1] = srcrow[(x - left) * 3 + 1]; tmp.col[k+2] = srcrow[(x - left) * 3 + 2]; } for (; x < tmp.width; x++) { int k = x * 3; row[k+0] = bg[0]; row[k+1] = bg[1]; row[k+2] = bg[2]; } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
static void load_gimp_brush (const gchar *fn, ppm_t *p) { FILE *f; struct _BrushHeader hdr; gchar *ptr; gint x, y; f = fopen_from_search_path (fn, "rb"); ppm_kill (p); if (!f) { g_printerr ("load_gimp_brush: Unable to open file \"%s\"!\n", gimp_filename_to_utf8 (fn)); ppm_new (p, 10,10); return; } fread (&hdr, 1, sizeof (struct _BrushHeader), f); for (x = 0; x < 7; x++) msb2lsb (&((unsigned int *)&hdr)[x]); ppm_new (p, hdr.width, hdr.height); ptr = g_malloc (hdr.width); fseek (f, hdr.header_size, SEEK_SET); for (y = 0; y < p->height; y++) { fread (ptr, p->width, 1, f); for (x = 0; x < p->width; x++) { int k = y * p->width * 3 + x * 3; p->col[k+0] = p->col[k+1] = p->col[k+2] = ptr[x]; } } fclose (f); g_free (ptr); }
void edgepad (ppm_t *p, int left,int right, int top, int bottom) { int x, y; ppm_t tmp = {0, 0, NULL}; guchar testcol[3] = {0, 255, 0}; int srowstride, drowstride; ppm_new (&tmp, p->width+left+right, p->height+top+bottom); fill (&tmp, testcol); srowstride = p->width * 3; drowstride = tmp.width * 3; for (y = 0; y < top; y++) { memcpy (&tmp.col[y * drowstride + left * 3], p->col, srowstride); } for (; y-top < p->height; y++) { memcpy (&tmp.col[y * drowstride + left * 3], p->col + (y - top) * srowstride, srowstride); } for (; y < tmp.height ; y++) { memcpy (&tmp.col[y * drowstride + left * 3], p->col + (p->height - 1) * srowstride, srowstride); } for (y = 0; y < tmp.height; y++) { guchar *col, *tmprow; tmprow = tmp.col + y*drowstride; col = tmp.col + y*drowstride + left*3; for (x = 0; x < left; x++) { memcpy (&tmprow[x * 3], col, 3); } col = tmp.col + y * drowstride + (tmp.width-right - 1) * 3; for (x = 0; x < right; x++) { memcpy (&tmprow[(x + tmp.width - right - 1) * 3], col, 3); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
static void update_orient_map_preview_prev (void) { int x, y; guchar black[3] = {0, 0, 0}; guchar gray[3] = {120, 120, 120}; guchar white[3] = {255, 255, 255}; if (!PPM_IS_INITED (&update_om_preview_nbuffer)) ppm_new (&update_om_preview_nbuffer,OMWIDTH,OMHEIGHT); fill (&update_om_preview_nbuffer, black); for (y = 6; y < OMHEIGHT-4; y += 10) for (x = 6; x < OMWIDTH-4; x += 10) { double dir = gimp_deg_to_rad (get_direction (x / (double)OMWIDTH, y / (double)OMHEIGHT,0)); double xo = sin (dir) * 4.0; double yo = cos (dir) * 4.0; ppm_drawline (&update_om_preview_nbuffer, x - xo, y - yo, x + xo, y + yo, gray); ppm_put_rgb (&update_om_preview_nbuffer, x - xo, y - yo, white); } gimp_preview_area_draw (GIMP_PREVIEW_AREA (orient_map_preview_prev), 0, 0, OMWIDTH, OMHEIGHT, GIMP_RGB_IMAGE, (guchar *)update_om_preview_nbuffer.col, OMWIDTH * 3); gtk_widget_queue_draw (orient_map_preview_prev); gtk_widget_set_sensitive (prev_button, (num_vectors > 1)); gtk_widget_set_sensitive (next_button, (num_vectors > 1)); gtk_widget_set_sensitive (add_button, (num_vectors < MAXORIENTVECT)); gtk_widget_set_sensitive (kill_button, (num_vectors > 1)); }
void blur (ppm_t *p, int xrad, int yrad) { int x, y, k; int tx, ty; ppm_t tmp = {0,0,NULL}; int r, g, b, n; int rowstride = p->width * 3; ppm_new (&tmp, p->width, p->height); for (y = 0; y < p->height; y++) { for (x = 0; x < p->width; x++) { r = g = b = n = 0; for (ty = y-yrad; ty <= y+yrad; ty++) { for (tx = x-xrad; tx <= x+xrad; tx++) { if (ty<0) continue; if (ty>=p->height) continue; if (tx<0) continue; if (tx>=p->width) continue; k = ty * rowstride + tx * 3; r += p->col[k+0]; g += p->col[k+1]; b += p->col[k+2]; n++; } } k = y * rowstride + x * 3; tmp.col[k+0] = r / n; tmp.col[k+1] = g / n; tmp.col[k+2] = b / n; } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
void crop (ppm_t *p, int lx, int ly, int hx, int hy) { ppm_t tmp = {0,0,NULL}; int x, y; int srowstride = p->width * 3; int drowstride; ppm_new (&tmp, hx - lx, hy - ly); drowstride = tmp.width * 3; for (y = ly; y < hy; y++) for (x = lx; x < hx; x++) memcpy (&tmp.col[(y - ly) * drowstride + (x - lx) * 3], &p->col[y * srowstride + x * 3], 3); ppm_kill (p); p->col = tmp.col; p->width = tmp.width; p->height = tmp.height; }
void resize (ppm_t *p, int nx, int ny) { int x, y; float xs = p->width / (float)nx; float ys = p->height / (float)ny; ppm_t tmp = {0, 0, NULL}; ppm_new (&tmp, nx, ny); for (y = 0; y < ny; y++) { guchar *row = tmp.col + y * tmp.width * 3; for (x = 0; x < nx; x++) { get_rgb (p, x * xs, y * ys, &row[x * 3]); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
void resize_fast (ppm_t *p, int nx, int ny) { int x, y; float xs = p->width / (float)nx; float ys = p->height / (float)ny; ppm_t tmp = {0, 0, NULL}; ppm_new (&tmp, nx, ny); for (y = 0; y < ny; y++) { for (x = 0; x < nx; x++) { gint rx = x * xs, ry = y * ys; memcpy (&tmp.col[y * tmp.width * 3 + x * 3], &p->col[ry * p->width * 3 + rx * 3], 3); } } ppm_kill (p); p->width = tmp.width; p->height = tmp.height; p->col = tmp.col; }
static void brushdmenuselect (GtkWidget *widget, gpointer data) { GimpPixelRgn src_rgn; guchar *src_row; guchar *src; gint id; gint bpp; gint x, y; ppm_t *p; gint x1, y1, x2, y2; gint row; GimpDrawable *drawable; gint rowstride; gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &id); if (id == -1) return; if (brush_from_file == 2) return; /* Not finished GUI-building yet */ if (brush_from_file) { #if 0 unselectall (brush_list); #endif preset_save_button_set_sensitive (FALSE); } gtk_adjustment_set_value (brush_gamma_adjust, 1.0); gtk_adjustment_set_value (brush_aspect_adjust, 0.0); drawable = gimp_drawable_get (id); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); bpp = gimp_drawable_bpp (drawable->drawable_id); ppm_kill (&brushppm); ppm_new (&brushppm, x2 - x1, y2 - y1); p = &brushppm; rowstride = p->width * 3; src_row = g_new (guchar, (x2 - x1) * bpp); gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, x2 - x1, y2 - y1, FALSE, FALSE); if (bpp == 3) { /* RGB */ int bpr = (x2 - x1) * 3; for (row = 0, y = y1; y < y2; row++, y++) { gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1)); memcpy (p->col + row*rowstride, src_row, bpr); } } else { /* RGBA (bpp > 3) GrayA (bpp == 2) or Gray */ gboolean is_gray = ((bpp > 3) ? TRUE : FALSE); for (row = 0, y = y1; y < y2; row++, y++) { guchar *tmprow = p->col + row * rowstride; guchar *tmprow_ptr; gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1)); src = src_row; tmprow_ptr = tmprow; /* Possible micro-optimization here: * src_end = src + src_rgn.bpp * (x2-x1); * for ( ; src < src_end ; src += src_rgn.bpp) */ for (x = x1; x < x2; x++) { *(tmprow_ptr++) = src[0]; *(tmprow_ptr++) = src[is_gray ? 1 : 0]; *(tmprow_ptr++) = src[is_gray ? 2 : 0]; src += src_rgn.bpp; } } } g_free (src_row); if (bpp >= 3) pcvals.color_brushes = 1; else pcvals.color_brushes = 0; brush_from_file = 0; update_brush_preview (NULL); }
void repaint (ppm_t *p, ppm_t *a) { int x, y; int tx = 0, ty = 0; ppm_t tmp = {0, 0, NULL}; ppm_t atmp = {0, 0, NULL}; int r, g, b, h, i, j, on, sn; int num_brushes, maxbrushwidth, maxbrushheight; guchar back[3] = {0, 0, 0}; ppm_t *brushes, *shadows; ppm_t *brush, *shadow = NULL; double *brushes_sum; int cx, cy, maxdist; double scale, relief, startangle, anglespan, density, bgamma; int max_progress; ppm_t paper_ppm = {0, 0, NULL}; ppm_t dirmap = {0, 0, NULL}; ppm_t sizmap = {0, 0, NULL}; int *xpos = NULL, *ypos = NULL; int progstep; static int running = 0; int dropshadow = pcvals.general_drop_shadow; int shadowblur = pcvals.general_shadow_blur; if (running) return; running++; runningvals = pcvals; /* Shouldn't be necessary, but... */ if (img_has_alpha) if ((p->width != a->width) || (p->height != a->height)) { g_printerr ("Huh? Image size != alpha size?\n"); return; } num_brushes = runningvals.orient_num * runningvals.size_num; startangle = runningvals.orient_first; anglespan = runningvals.orient_last; density = runningvals.brush_density; if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST) density /= 3.0; bgamma = runningvals.brushgamma; brushes = g_malloc (num_brushes * sizeof (ppm_t)); brushes_sum = g_malloc (num_brushes * sizeof (double)); if (dropshadow) shadows = g_malloc (num_brushes * sizeof (ppm_t)); else shadows = NULL; brushes[0].col = NULL; brush_get_selected (&brushes[0]); resize (&brushes[0], brushes[0].width, brushes[0].height * pow (10, runningvals.brush_aspect)); scale = runningvals.size_last / MAX (brushes[0].width, brushes[0].height); if (bgamma != 1.0) ppm_apply_gamma (&brushes[0], 1.0 / bgamma, 1,1,1); resize (&brushes[0], brushes[0].width * scale, brushes[0].height * scale); i = 1 + sqrt (brushes[0].width * brushes[0].width + brushes[0].height * brushes[0].height); ppm_pad (&brushes[0], i-brushes[0].width, i-brushes[0].width, i - brushes[0].height, i - brushes[0].height, back); for (i = 1; i < num_brushes; i++) { brushes[i].col = NULL; ppm_copy (&brushes[0], &brushes[i]); } for (i = 0; i < runningvals.size_num; i++) { double sv; if (runningvals.size_num > 1) sv = i / (runningvals.size_num - 1.0); else sv = 1.0; for (j = 0; j < runningvals.orient_num; j++) { h = j + i * runningvals.orient_num; free_rotate (&brushes[h], startangle + j * anglespan / runningvals.orient_num); rescale (&brushes[h], ( sv * runningvals.size_first + (1.0-sv) * runningvals.size_last ) / runningvals.size_last); autocrop (&brushes[h],1); } } /* Brush-debugging */ #if 0 for (i = 0; i < num_brushes; i++) { char tmp[1000]; g_snprintf (tmp, sizeof (tmp), "/tmp/_brush%03d.ppm", i); ppm_save (&brushes[i], tmp); } #endif for (i = 0; i < num_brushes; i++) { if (!runningvals.color_brushes) prepare_brush (&brushes[i]); brushes_sum[i] = sum_brush (&brushes[i]); } brush = &brushes[0]; maxbrushwidth = maxbrushheight = 0; for (i = 0; i < num_brushes; i++) { if (brushes[i].width > maxbrushwidth) maxbrushwidth = brushes[i].width; if (brushes[i].height > maxbrushheight) maxbrushheight = brushes[i].height; } for (i = 0; i < num_brushes; i++) { int xp, yp; guchar blk[3] = {0, 0, 0}; xp = maxbrushwidth - brushes[i].width; yp = maxbrushheight - brushes[i].height; if (xp || yp) ppm_pad (&brushes[i], xp / 2, xp - xp / 2, yp / 2, yp - yp / 2, blk); } if (dropshadow) { for (i = 0; i < num_brushes; i++) { shadows[i].col = NULL; ppm_copy (&brushes[i], &shadows[i]); ppm_apply_gamma (&shadows[i], 0, 1,1,0); ppm_pad (&shadows[i], shadowblur*2, shadowblur*2, shadowblur*2, shadowblur*2, back); for (j = 0; j < shadowblur; j++) blur (&shadows[i], 2, 2); #if 0 autocrop (&shadows[i],1); #endif } #if 0 maxbrushwidth += shadowdepth*3; maxbrushheight += shadowdepth*3; #endif } /* For extra annoying debugging :-) */ #if 0 ppm_save (brushes, "/tmp/__brush.ppm"); if (shadows) ppm_save (shadows, "/tmp/__shadow.ppm"); system ("xv /tmp/__brush.ppm & xv /tmp/__shadow.ppm & "); #endif if (runningvals.general_paint_edges) { edgepad (p, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight); if (img_has_alpha) edgepad (a, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight); } if (img_has_alpha) { /* Initially fully transparent */ if (runningvals.general_background_type == BG_TYPE_TRANSPARENT) { guchar tmpcol[3] = {255, 255, 255}; ppm_new (&atmp, a->width, a->height); fill (&atmp, tmpcol); } else { ppm_copy (a, &atmp); } } if (runningvals.general_background_type == BG_TYPE_SOLID) { guchar tmpcol[3]; ppm_new (&tmp, p->width, p->height); gimp_rgb_get_uchar (&runningvals.color, &tmpcol[0], &tmpcol[1], &tmpcol[2]); fill (&tmp, tmpcol); } else if (runningvals.general_background_type == BG_TYPE_KEEP_ORIGINAL) { ppm_copy (p, &tmp); } else { int dx, dy; ppm_new (&tmp, p->width, p->height); ppm_load (runningvals.selected_paper, &paper_ppm); if (runningvals.paper_scale != 100.0) { scale = runningvals.paper_scale / 100.0; resize (&paper_ppm, paper_ppm.width * scale, paper_ppm.height * scale); } if (runningvals.paper_invert) ppm_apply_gamma (&paper_ppm, -1.0, 1, 1, 1); dx = runningvals.general_paint_edges ? paper_ppm.width - maxbrushwidth : 0; dy = runningvals.general_paint_edges ? paper_ppm.height - maxbrushheight : 0; for (y = 0; y < tmp.height; y++) { int lx; int ry = (y + dy) % paper_ppm.height; for (x = 0; x < tmp.width; x+=lx) { int rx = (x + dx) % paper_ppm.width; lx = MIN (tmp.width - x, paper_ppm.width - rx); memcpy (&tmp.col[y * tmp.width * 3 + x * 3], &paper_ppm.col[ry * paper_ppm.width * 3 + rx * 3], 3 * lx); } } } cx = p->width / 2; cy = p->height / 2; maxdist = sqrt (cx * cx + cy * cy); switch (runningvals.orient_type) { case ORIENTATION_VALUE: ppm_new (&dirmap, p->width, p->height); for (y = 0; y < dirmap.height; y++) { guchar *dstrow = &dirmap.col[y * dirmap.width * 3]; guchar *srcrow = &p->col[y * p->width * 3]; for (x = 0; x < dirmap.width; x++) { dstrow[x * 3] = (srcrow[x * 3] + srcrow[x * 3 + 1] + srcrow[x * 3 + 2]) / 3; } } break; case ORIENTATION_RADIUS: ppm_new (&dirmap, p->width, p->height); for (y = 0; y < dirmap.height; y++) { guchar *dstrow = &dirmap.col[y * dirmap.width * 3]; double ysqr = (cy - y) * (cy - y); for (x = 0; x < dirmap.width; x++) { dstrow[x*3] = sqrt ((cx - x) * (cx - x) + ysqr) * 255 / maxdist; } } break; case ORIENTATION_RADIAL: ppm_new (&dirmap, p->width, p->height); for (y = 0; y < dirmap.height; y++) { guchar *dstrow = &dirmap.col[y * dirmap.width * 3]; for (x = 0; x < dirmap.width; x++) { dstrow[x * 3] = (G_PI + atan2 (cy - y, cx - x)) * 255.0 / (G_PI * 2); } } break; case ORIENTATION_FLOWING: ppm_new (&dirmap, p->width / 6 + 5, p->height / 6 + 5); mkgrayplasma (&dirmap, 15); blur (&dirmap, 2, 2); blur (&dirmap, 2, 2); resize (&dirmap, p->width, p->height); blur (&dirmap, 2, 2); if (runningvals.general_paint_edges) edgepad (&dirmap, maxbrushwidth, maxbrushheight, maxbrushwidth, maxbrushheight); break; case ORIENTATION_HUE: ppm_new (&dirmap, p->width, p->height); for (y = 0; y < dirmap.height; y++) { guchar *dstrow = &dirmap.col[y * dirmap.width * 3]; guchar *srcrow = &p->col[y * p->width * 3]; for (x = 0; x < dirmap.width; x++) { dstrow[x * 3] = get_hue (&srcrow[x * 3]); } } break; case ORIENTATION_ADAPTIVE: { guchar tmpcol[3] = {0, 0, 0}; ppm_new (&dirmap, p->width, p->height); fill (&dirmap, tmpcol); } break; case ORIENTATION_MANUAL: ppm_new (&dirmap, p->width-maxbrushwidth*2, p->height-maxbrushheight*2); for (y = 0; y < dirmap.height; y++) { guchar *dstrow = &dirmap.col[y * dirmap.width * 3]; double tmpy = y / (double)dirmap.height; for (x = 0; x < dirmap.width; x++) { dstrow[x * 3] = get_pixel_value(90 - get_direction(x / (double)dirmap.width, tmpy, 1)); } } edgepad (&dirmap, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight); break; } if (runningvals.size_type == SIZE_TYPE_VALUE) { ppm_new (&sizmap, p->width, p->height); for (y = 0; y < sizmap.height; y++) { guchar *dstrow = &sizmap.col[y * sizmap.width * 3]; guchar *srcrow = &p->col[y * p->width * 3]; for (x = 0; x < sizmap.width; x++) { dstrow[x * 3] = (srcrow[x * 3] + srcrow[x * 3 + 1] + srcrow[x * 3 + 2]) / 3; } } } else if (runningvals.size_type == SIZE_TYPE_RADIUS) { ppm_new (&sizmap, p->width, p->height); for (y = 0; y < sizmap.height; y++) { guchar *dstrow = &sizmap.col[y * sizmap.width * 3]; double ysqr = (cy - y) * (cy - y); for (x = 0; x < sizmap.width; x++) { dstrow[x * 3] = sqrt ((cx - x) * (cx - x) + ysqr) * 255 / maxdist; } } } else if (runningvals.size_type == SIZE_TYPE_RADIAL) { ppm_new (&sizmap, p->width, p->height); for (y = 0; y < sizmap.height; y++) { guchar *dstrow = &sizmap.col[y * sizmap.width * 3]; for (x = 0; x < sizmap.width; x++) { dstrow[x * 3] = (G_PI + atan2 (cy - y, cx - x)) * 255.0 / (G_PI * 2); } } } else if (runningvals.size_type == SIZE_TYPE_FLOWING) { ppm_new (&sizmap, p->width / 6 + 5, p->height / 6 + 5); mkgrayplasma (&sizmap, 15); blur (&sizmap, 2, 2); blur (&sizmap, 2, 2); resize (&sizmap, p->width, p->height); blur (&sizmap, 2, 2); if (runningvals.general_paint_edges) edgepad (&sizmap, maxbrushwidth, maxbrushheight, maxbrushwidth, maxbrushheight); } else if (runningvals.size_type == SIZE_TYPE_HUE) { ppm_new (&sizmap, p->width, p->height); for (y = 0; y < sizmap.height; y++) { guchar *dstrow = &sizmap.col[y * sizmap.width * 3]; guchar *srcrow = &p->col[y * p->width * 3]; for (x = 0; x < sizmap.width; x++) { dstrow[ x * 3] = get_hue (&srcrow[x * 3]); } } } else if (runningvals.size_type == SIZE_TYPE_ADAPTIVE) { guchar tmpcol[3] = {0, 0, 0}; ppm_new (&sizmap, p->width, p->height); fill (&sizmap, tmpcol); } else if (runningvals.size_type == SIZE_TYPE_MANUAL) { ppm_new (&sizmap, p->width-maxbrushwidth * 2, p->height-maxbrushheight * 2); for (y = 0; y < sizmap.height; y++) { guchar *dstrow = &sizmap.col[y * sizmap.width * 3]; double tmpy = y / (double)sizmap.height; for (x = 0; x < sizmap.width; x++) { dstrow[x * 3] = 255 * (1.0 - get_siz_from_pcvals (x / (double)sizmap.width, tmpy)); } } edgepad (&sizmap, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight); } #if 0 ppm_save(&sizmap, "/tmp/_sizmap.ppm"); #endif if (runningvals.place_type == PLACEMENT_TYPE_RANDOM) { i = tmp.width * tmp.height / (maxbrushwidth * maxbrushheight); i *= density; } else if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST) { i = (int)(tmp.width * density / maxbrushwidth) * (int)(tmp.height * density / maxbrushheight); #if 0 g_printerr("i=%d\n", i); #endif } if (i < 1) i = 1; max_progress = i; progstep = max_progress / 30; if (progstep < 10) progstep = 10; if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST) { int j; xpos = g_new (int, i); ypos = g_new (int, i); for (j = 0; j < i; j++) { int factor = (int)(tmp.width * density / maxbrushwidth + 0.5); if (factor < 1) factor = 1; xpos[j] = maxbrushwidth/2 + (j % factor) * maxbrushwidth / density; ypos[j] = maxbrushheight/2 + (j / factor) * maxbrushheight / density; } for (j = 0; j < i; j++) { int a, b; a = g_rand_int_range (random_generator, 0, i); b = xpos[j]; xpos[j] = xpos[a]; xpos[a] = b; b = ypos[j]; ypos[j] = ypos[a]; ypos[a] = b; } }
void autocrop (ppm_t *p, int room) { int lx = 0, hx = p->width, ly = 0, hy = p->height; int x, y, n = 0; guchar tc[3]; ppm_t tmp = {0,0,NULL}; int rowstride = p->width * 3; int drowstride; /* upper */ memcpy (&tc, p->col, 3); for (y = 0; y < p->height; y++) { n = 0; for (x = 0; x < p->width; x++) { if (memcmp (&tc, &p->col[y*rowstride+x*3], 3)) { n++; break; } } if (n) break; } if (n) ly = y; #if 0 printf("ly = %d\n", ly); #endif /* lower */ memcpy (&tc, &p->col[(p->height - 1) * rowstride], 3); for (y = p->height-1; y >= 0; y--) { n = 0; for (x = 0; x < p->width; x++) { if (memcmp (&tc, &p->col[y*rowstride+x*3], 3)) { n++; break; } } if (n) break; } if (n) hy = y+1; if (hy >= p->height) hy = p->height - 1; #if 0 printf("hy = %d\n", hy); #endif /* left */ memcpy (&tc, &p->col[ly * rowstride], 3); for (x = 0; x < p->width; x++) { n = 0; for (y = ly; y <= hy && y < p->height; y++) { if (memcmp (&tc, &p->col[y * rowstride + x * 3], 3)) { n++; break; } } if (n) break; } if (n) lx = x; #if 0 printf("lx = %d\n", lx); #endif /* right */ memcpy (&tc, &p->col[ly * rowstride + (p->width - 1) * 3], 3); for (x = p->width-1; x >= 0; x--) { n = 0; for (y = ly; y <= hy; y++) { if (memcmp (&tc, &p->col[y * rowstride + x * 3], 3)) { n++; break; } } if (n) break; } if (n) hx = x + 1; #if 0 printf("hx = %d\n", hx); #endif lx -= room; if (lx < 0) lx = 0; ly -= room; if (ly < 0) ly = 0; hx += room; if (hx >= p->width) hx = p->width - 1; hy += room; if (hy >= p->height) hy = p->height - 1; ppm_new (&tmp, hx - lx, hy - ly); drowstride = tmp.width * 3; for (y = ly; y < hy; y++) for (x = lx; x < hx; x++) memcpy (&tmp.col[(y - ly) * drowstride + (x - lx) * 3], &p->col[y * rowstride + x * 3], 3); ppm_kill (p); p->col = tmp.col; p->width = tmp.width; p->height = tmp.height; }
void ppm_load (const char *fn, ppm_t *p) { char line[200]; int y, pgm = 0; FILE *f; if (!strcmp (&fn[strlen (fn)-4], ".gbr")) { load_gimp_brush(fn, p); return; } f = fopen_from_search_path (fn, "rb"); ppm_kill (p); if (!f) { g_printerr ("ppm_load: Unable to open file \"%s\"!\n", gimp_filename_to_utf8 (fn)); ppm_new (p, 10,10); return; } readline (f, line, 200); if (strcmp (line, "P6")) { if (strcmp (line, "P5")) { fclose (f); g_printerr ("ppm_load: File \"%s\" not PPM/PGM? (line=\"%s\")%c\n", gimp_filename_to_utf8 (fn), line, 7); ppm_new (p, 10,10); return; } pgm = 1; } readline (f, line, 200); p->width = atoi (line); p->height = atoi (strchr (line, ' ')+1); readline (f, line, 200); if (strcmp (line, "255")) { g_printerr ("ppm_load: File \"%s\" not valid PPM/PGM? (line=\"%s\")%c\n", gimp_filename_to_utf8 (fn), line, 7); ppm_new (p, 10,10); return; } p->col = g_malloc (p->height * p->width * 3); if (!pgm) { fread (p->col, p->height * 3 * p->width, 1, f); } else { guchar *tmpcol = g_malloc (p->width * p->height); fread (tmpcol, p->height * p->width, 1, f); for (y = 0; y < p->width * p->height * 3; y++) { p->col[y] = tmpcol[y / 3]; } } fclose (f); }