static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglRectangle boundary = get_effective_area (operation); const Babl *format = babl_format ("RGBA float"); gint x,y; gfloat *src_buf, *dst_buf; gfloat dest[4]; gint i, offset = 0; gboolean inside; gdouble px, py; GeglMatrix2 scale; /* a matrix indicating scaling factors around the current center pixel. */ src_buf = g_new0 (gfloat, result->width * result->height * 4); dst_buf = g_new0 (gfloat, result->width * result->height * 4); gegl_buffer_get (input, result, 1.0, format, src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); if (o->middle) { o->pole_x = boundary.width / 2; o->pole_y = boundary.height / 2; } for (y = result->y; y < result->y + result->height; y++) for (x = result->x; x < result->x + result->width; x++) { #define gegl_unmap(u,v,ud,vd) { \ gdouble rx, ry; \ inside = calc_undistorted_coords ((gdouble)x, (gdouble)y, \ &rx, &ry, o, boundary); \ ud = rx; \ vd = ry; \ } gegl_sampler_compute_scale (scale, x, y); gegl_unmap(x,y,px,py); #undef gegl_unmap if (inside) gegl_buffer_sample (input, px, py, &scale, dest, format, GEGL_SAMPLER_NOHALO, GEGL_ABYSS_NONE); else for (i=0; i<4; i++) dest[i] = 0.0; for (i=0; i<4; i++) dst_buf[offset++] = dest[i]; } gegl_buffer_set (output, result, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE); g_free (src_buf); g_free (dst_buf); return TRUE; }
static gboolean process (GeglOperation *op, void *in_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (op); gint num_sampling_points; GeglCurve *curve; gint i; gfloat *in = in_buf; gfloat *out = out_buf; gdouble *xs, *ys; num_sampling_points = o->sampling_points; curve = o->curve; if (num_sampling_points > 0) { xs = g_new(gdouble, num_sampling_points); ys = g_new(gdouble, num_sampling_points); gegl_curve_calc_values(o->curve, 0.0, 1.0, num_sampling_points, xs, ys); g_free(xs); for (i=0; i<samples; i++) { gint x = in[0] * num_sampling_points; gfloat y; if (x < 0) y = ys[0]; else if (x >= num_sampling_points) y = ys[num_sampling_points - 1]; else y = ys[x]; out[0] = y; out[1]=in[1]; in += 2; out+= 2; } g_free(ys); } else for (i=0; i<samples; i++) { gfloat u = in[0]; out[0] = gegl_curve_calc_value(curve, u); out[1]=in[1]; in += 2; out+= 2; } return TRUE; }
static void prepare (GeglOperation *operation) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); Priv *p = (Priv*)o->chant_data; if (p == NULL) init (o); p = (Priv*)o->chant_data; g_assert (o->chant_data != NULL); gegl_operation_set_format (operation, "output", babl_format ("R'G'B'A u8")); if (!p->loadedfilename || strcmp (p->loadedfilename, o->path)) { gint i; gint err; ff_cleanup (o); err = av_open_input_file (&p->ic, o->path, NULL, 0, NULL); if (err < 0) { print_error (o->path, err); } err = av_find_stream_info (p->ic); if (err < 0) { g_warning ("ff-load: error finding stream info for %s", o->path); return; } for (i = 0; i< p->ic->nb_streams; i++) { AVCodecContext *c = p->ic->streams[i]->codec; #if LIBAVFORMAT_VERSION_MAJOR >= 53 if (c->codec_type == AVMEDIA_TYPE_VIDEO) #else if (c->codec_type == CODEC_TYPE_VIDEO) #endif { p->video_st = p->ic->streams[i]; p->video_stream = i; } } p->enc = p->video_st->codec; p->codec = avcodec_find_decoder (p->enc->codec_id); /* p->enc->error_resilience = 2; */ p->enc->error_concealment = 3; p->enc->workaround_bugs = FF_BUG_AUTODETECT; if (p->codec == NULL) { g_warning ("codec not found"); } if (p->codec->capabilities & CODEC_CAP_TRUNCATED) p->enc->flags |= CODEC_FLAG_TRUNCATED; if (avcodec_open (p->enc, p->codec) < 0) { g_warning ("error opening codec %s", p->enc->codec->name); return; } p->width = p->enc->width; p->height = p->enc->height; p->frames = 10000000; p->lavc_frame = avcodec_alloc_frame (); if (p->fourcc) g_free (p->fourcc); p->fourcc = g_strdup ("none"); p->fourcc[0] = (p->enc->codec_tag) & 0xff; p->fourcc[1] = (p->enc->codec_tag >> 8) & 0xff; p->fourcc[2] = (p->enc->codec_tag >> 16) & 0xff; p->fourcc[3] = (p->enc->codec_tag >> 24) & 0xff; if (p->codec_name) g_free (p->codec_name); if (p->codec->name) { p->codec_name = g_strdup (p->codec->name); } else { p->codec_name = g_strdup (""); } if (p->loadedfilename) g_free (p->loadedfilename); p->loadedfilename = g_strdup (o->path); p->prevframe = -1; p->coded_bytes = 0; p->coded_buf = NULL; }
static gboolean process (GeglOperation *operation, void *in_buf, void *out_buf, glong n_pixels, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gdouble noise_coeff = 0.0; int rint = 0; gint b, i; gint x, y; gdouble noise[4]; gfloat tmp; gfloat * GEGL_ALIGNED in_pixel; gfloat * GEGL_ALIGNED out_pixel; in_pixel = in_buf; out_pixel = out_buf; noise[0] = o->red; noise[1] = o->green; noise[2] = o->blue; noise[3] = o->alpha; x = roi->x; y = roi->y; for (i=0; i<n_pixels; i++) { for (b = 0; b < 4; b++) { if (b == 0 || o->independent || b == 3 ) noise_coeff = noise[b] * gauss (o->seed, &rint, x, y) * 0.5; if (noise[b] > 0.0) { if (o->correlated) { tmp = (in_pixel[b] + (in_pixel[b] * (noise_coeff / 0.5)) ); } else { tmp = (in_pixel[b] + noise_coeff ); } out_pixel[b] = CLAMP(tmp, 0.0, 1.0); } else { out_pixel[b] = in_pixel[b]; } } in_pixel += 4; out_pixel += 4; x++; if (x >= roi->x + roi->width) { x = roi->x; y++; } } return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation); gfloat *src_buf; gfloat *dst_buf; gint n_pixels = result->width * result->height; GeglRectangle src_rect; gfloat *current_pix; gfloat *target_pix; gfloat *dst_pix; gint x, y; gint total_src_pixels; gint total_dst_pixels; gint bleed_max; gint bleed_index; gfloat blend_coefficient; GHashTable *bleed_table; static GMutex mutex = { 0, }; g_mutex_lock (&mutex); if (!o->chant_data) { o->chant_data = g_hash_table_new_full (tuple_hash, tuple_equal, g_free, g_free); calculate_bleed (operation, input); } g_mutex_unlock (&mutex); bleed_table = (GHashTable*) o->chant_data; src_rect.x = result->x - op_area->left; src_rect.width = result->width + op_area->left + op_area->right; src_rect.y = result->y - op_area->top; src_rect.height = result->height + op_area->top + op_area->bottom; total_src_pixels = src_rect.width * src_rect.height; total_dst_pixels = result->width * result->height; src_buf = gegl_malloc (4 * total_src_pixels * sizeof (gfloat)); dst_buf = gegl_malloc (4 * total_dst_pixels * sizeof (gfloat)); gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RGBA float"), src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); current_pix = src_buf + 4*(o->strength + src_rect.width * o->strength); dst_pix = dst_buf; x = 0; y = 0; n_pixels = result->width * result->height; bleed_max = 0; bleed_index = 0; while (n_pixels--) { gint i; pair key = {x + result->x, y + result->y}; gint *bleed = g_hash_table_lookup (bleed_table, &key); if (x == 0) { for (i = 0; i < o->strength; i++) { pair key = {result->x - i, y + result->y}; gint *bleed = g_hash_table_lookup (bleed_table, &key); if (bleed) { bleed_max = *bleed; bleed_index = *bleed - i; break; } } } for (i = 0; i < 4; i++) dst_pix[i] = current_pix[i]; if (bleed) { gfloat blend_color[4]; gfloat blend_amount[4]; gfloat *blend_pix; bleed_max = *bleed; bleed_index = *bleed; target_pix = current_pix; blend_pix = current_pix - 12; for (i = 0; i < 4; i++) { blend_amount[i] = target_pix[i] - blend_pix[i]; blend_color[i] = blend_pix[i] + blend_amount[i]; dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0; } } else if (bleed_index > 0) { gfloat blend_color[4]; gfloat blend_amount[4]; gfloat *blend_pix; bleed_index--; blend_coefficient = 1.0 - ((gfloat) bleed_index)/(gfloat) bleed_max; blend_pix = current_pix - 4 * (bleed_max - bleed_index) - 12; target_pix = current_pix; for (i = 0; i < 4; i++) { blend_amount[i] = target_pix[i] - blend_pix[i]; blend_color[i] = blend_pix[i] + blend_amount[i] * blend_coefficient; dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0; } } x++; current_pix += 4; dst_pix += 4; if (x >= result->width) { bleed_max = 0; bleed_index = 0; x = 0; y++; current_pix += 8 * o->strength; } } gegl_buffer_set (output, result, 1, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE); gegl_free (src_buf); gegl_free (dst_buf); return TRUE; }
static gboolean process (GeglOperation *operation, void *in_buf, void *out_buf, glong n_pixels, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gfloat *GEGL_ALIGNED in_pixel; gfloat *GEGL_ALIGNED out_pixel; GeglRectangle whole_region; gfloat lightness, chroma, hue, alpha; gint i; gint x, y; in_pixel = in_buf; out_pixel = out_buf; x = roi->x; y = roi->y; whole_region = *(gegl_operation_source_get_bounding_box (operation, "input")); for (i = 0; i < n_pixels; i++) { /* n is independent from the roi, but from the whole image */ gint n = (3 * o->holdness + 4) * (x + whole_region.width * y); lightness = in_pixel[0]; chroma = in_pixel[1]; hue = in_pixel[2]; alpha = in_pixel[3]; if ((o->hue_distance > 0) && (chroma > 0)) hue = randomize_value (hue, 0.0, 359.0, TRUE, o->hue_distance, o->holdness, x, y, n, o->rand); n += o->holdness + 1; if (o->chroma_distance > 0) { if (chroma == 0) hue = gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 360.0); chroma = randomize_value (chroma, 0.0, 100.0, FALSE, o->chroma_distance, o->holdness, x, y, n+1, o->rand); } n += o->holdness + 2; if (o->lightness_distance > 0) lightness = randomize_value (lightness, 0.0, 100.0, FALSE, o->lightness_distance, o->holdness, x, y, n, o->rand); /*n += o->holdness + 1*/ out_pixel[0] = lightness; out_pixel[1] = chroma; out_pixel[2] = hue; out_pixel[3] = alpha; in_pixel += 4; out_pixel += 4; x++; if (x >= roi->x + roi->width) { x = roi->x; y++; } } return TRUE; }
static void prepare (GeglOperation *operation) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); Priv *p= (Priv*)o->chant_data; if (p == NULL) init (o); p = (Priv*)o->chant_data; gegl_operation_set_format (operation, "output", babl_format_new ( babl_model ("R'G'B'"), babl_type ("u8"), babl_component ("B'"), babl_component ("G'"), babl_component ("R'"), NULL)); p->w = o->width; p->h = o->height; if (!p->vd) { p->vd = g_malloc0 (sizeof (v4ldevice)); if (v4lopen (o->path, p->vd)) return; p->active = 1; if (v4lmmap (p->vd)) return; v4lsetdefaultnorm (p->vd, VIDEO_MODE_PAL); v4lgetcapability (p->vd); if (!(p->vd->capability.type & VID_TYPE_CAPTURE)) { g_warning ( "video_init: This device seems not to support video capturing.\n"); return; } } if (p->w != p->w_stored || p->h != p->h_stored) { if (p->w > p->vd->capability.maxwidth || p->h > p->vd->capability.maxheight) { p->w = p->vd->capability.maxwidth; p->h = p->vd->capability.maxheight; o->width = p->w; o->height = p->h; g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h); } else if (p->w < p->vd->capability.minwidth || p->h < p->vd->capability.minheight) { p->w = p->vd->capability.minwidth; p->h = p->vd->capability.minheight; o->width = p->w; o->height = p->h; g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h); } p->w_stored = p->w; p->h_stored = p->h; /* FIXME: try other palettes as well, do some profiling on the spca * based cameras to see what is the ideal format wrt performance */ if (!v4lsetpalette (p->vd, VIDEO_PALETTE_RGB24)) { p->decode=0; } else if (!v4lsetpalette (p->vd, VIDEO_PALETTE_YUV420P)) { p->decode=1; } else { g_warning ( "oops,. no usable v4l format found\n"); return; } v4lgrabinit (p->vd, p->w, p->h); v4lgrabf (p->vd); } }
static gboolean process (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglBuffer *source; SDL_Surface **sdl_outwin = NULL; /*op_sym (op, "sdl_outwin");*/ init_sdl (); if (!handle) handle = g_timeout_add (500, idle, NULL); if (!o->screen || o->width != result->width || o->height != result->height) { if (sdl_outwin) { if (o->screen) { SDL_FreeSurface (o->screen); o->screen = NULL; } o->screen = SDL_CreateRGBSurface (SDL_SWSURFACE, result->width, result->height, 32, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); *sdl_outwin = o->screen; if (!o->screen) { fprintf (stderr, "CreateRGBSurface failed: %s\n", SDL_GetError ()); return -1; } } else { o->screen = SDL_SetVideoMode (result->width, result->height, 32, SDL_SWSURFACE); if (!o->screen) { fprintf (stderr, "Unable to set SDL mode: %s\n", SDL_GetError ()); return -1; } } o->width = result->width ; o->height = result->height; } /* * There seems to be a valid faster path to the SDL desired display format * in B'G'R'A, perhaps babl should have been able to figure this out ito? * */ source = gegl_buffer_create_sub_buffer (input, result); gegl_buffer_get (source, 1.0, NULL, babl_format_new (babl_model ("RGBA"), babl_type ("u8"), babl_component ("B"), babl_component ("G"), babl_component ("R"), babl_component ("A"), NULL), ((SDL_Surface*)o->screen)->pixels, GEGL_AUTO_ROWSTRIDE); g_object_unref (source); if (!sdl_outwin) { SDL_UpdateRect (o->screen, 0, 0, 0, 0); SDL_WM_SetCaption (o->window_title, o->icon_title); } o->width = result->width ; o->height = result->height; return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gint x = result->x; /* initial x */ gint y = result->y; /* and y coordinates */ gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat)); gfloat *out_pixel = dst_buf; GeglSampler *sampler = gegl_buffer_sampler_new (input, babl_format ("RGBA float"), o->sampler_type); gint n_pixels = result->width * result->height; while (n_pixels--) { gdouble coordsx = 0.0; gdouble coordsy = 0.0; gdouble radius = 0.0; gdouble shift = 0.0; gdouble ux = 0.0; /* unit vector of the radius */ gdouble uy = 0.0; gdouble vx = 0.0; /* orthogonal vector of u */ gdouble vy = 0.0; gdouble dx = 0.0; gdouble dy = 0.0; dx = (gdouble)x-o->x; dy = (gdouble)y-o->y; radius = sqrt( dx * dx + dy * dy ); shift = o->amplitude * sin(2.0 * G_PI * radius / o->period + 2.0 * G_PI * o->phi); ux = dx / radius; uy = dy / radius; vx = -uy; vy = ux; coordsx = x + shift * vx; coordsy = y + shift * vy; gegl_sampler_get (sampler, coordsx, coordsy, NULL, out_pixel); out_pixel += 4; /* update x and y coordinates */ x++; if (x>=result->x + result->width) { x=result->x; y++; } } gegl_buffer_set (output, result, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE); g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf); g_object_unref (sampler); return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); Priv *p = (Priv*)o->chant_data; guchar *capbuf; static gboolean inited = FALSE; if (!inited && o->fps != 0) { inited= TRUE; g_timeout_add (1000/o->fps, update, operation); } if (!p->active) return FALSE; v4lgrabf (p->vd); capbuf = v4lgetaddress (p->vd); v4lsyncf (p->vd); if (!capbuf) { g_warning ("no capbuf found"); return FALSE; } if (p->decode) { guchar foobuf[o->width*o->height*3]; /* XXX: foobuf is unneeded the conversions resets for every * scanline and could thus have been done in a line by line * manner an fed into the output buffer */ gint y; for (y = 0; y < p->h; y++) { gint x; guchar *dst = &foobuf[y*p->w*3]; guchar *ysrc = (guchar *) (capbuf + (y) * (p->w) * 1); guchar *usrc = (guchar *) (capbuf + (p->w) * (p->h) + (y) / 2 * (p->w) / 2); guchar *vsrc = (guchar *) (capbuf + (p->w) * (p->h) + ((p->w) * (p->h)) / 4 + (y) / 2 * (p->w) / 2); for (x = 0; x < p->w; x++) { gint R, G, B; #ifndef byteclamp #define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0) #endif #define YUV82RGB8(Y,U,V,R,G,B)do{\ R= ((Y<<15) + 37355*(V-128))>>15;\ G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\ B= ((Y<<15) +66454* (U-128) )>>15;\ byteclamp(R);\ byteclamp(G);\ byteclamp(B);\ }while(0) /* the format support for this code is not very good, but it * works for the devices I have tested with, conversion even * for chroma subsampled images is something we should let * babl handle. */ YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B); dst[0] = B; dst[1] = G; dst[2] = R; dst += 3; ysrc++; if (x % 2) { usrc++; vsrc++; } } } gegl_buffer_set (output, NULL, NULL, foobuf, GEGL_AUTO_ROWSTRIDE); } else { gegl_buffer_set (output, NULL, NULL, capbuf, GEGL_AUTO_ROWSTRIDE); } return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *roi, gint level) { GeglRectangle src_rect; GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglOperationAreaFilter *op_area; gfloat* in_buf; gfloat* out_buf; gfloat* out_pixel; gint x,y; gdouble theta = o->angle * G_PI / 180.0; gdouble offset_x = o->length * cos(theta); gdouble offset_y = o->length * sin(theta); gint num_steps = (gint)ceil(o->length) + 1; gfloat inv_num_steps = 1.0f / num_steps; op_area = GEGL_OPERATION_AREA_FILTER (operation); src_rect = *roi; src_rect.x -= op_area->left; src_rect.y -= op_area->top; src_rect.width += op_area->left + op_area->right; src_rect.height += op_area->top + op_area->bottom; if (gegl_cl_is_accelerated ()) if (cl_process (operation, input, output, roi, &src_rect)) return TRUE; in_buf = g_new (gfloat, src_rect.width * src_rect.height * 4); out_buf = g_new0 (gfloat, roi->width * roi->height * 4); out_pixel = out_buf; gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RaGaBaA float"), in_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); for (y=0; y<roi->height; ++y) { for (x=0; x<roi->width; ++x) { gint step; gint c; gint px = x+roi->x; gint py = y+roi->y; gfloat sum[4] = {0,0,0,0}; for (step=0; step<num_steps; ++step) { gdouble t = num_steps == 1 ? 0.0 : step / (gdouble)(num_steps-1) - 0.5; /* get the interpolated pixel position for this step */ gdouble xx = px + t*offset_x; gdouble yy = py + t*offset_y; gint ix = (gint)floor(xx); gint iy = (gint)floor(yy); gdouble dx = xx - floor(xx); gdouble dy = yy - floor(yy); /* do bilinear interpolation to get a nice smooth result */ gfloat *pix0, *pix1, *pix2, *pix3; gfloat mixy0[4]; gfloat mixy1[4]; pix0 = get_pixel_color(in_buf, &src_rect, ix, iy); pix1 = get_pixel_color(in_buf, &src_rect, ix+1, iy); pix2 = get_pixel_color(in_buf, &src_rect, ix, iy+1); pix3 = get_pixel_color(in_buf, &src_rect, ix+1, iy+1); for (c=0; c<4; ++c) { mixy0[c] = dy*(pix2[c] - pix0[c]) + pix0[c]; mixy1[c] = dy*(pix3[c] - pix1[c]) + pix1[c]; sum[c] += dx*(mixy1[c] - mixy0[c]) + mixy0[c]; } } for (c=0; c<4; ++c) *out_pixel++ = sum[c] * inv_num_steps; } } gegl_buffer_set (output, roi, 0, babl_format ("RaGaBaA float"), out_buf, GEGL_AUTO_ROWSTRIDE); g_free (in_buf); g_free (out_buf); return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation); GeglBuffer *tmp; gfloat *src_buf; gfloat *dst_buf; gfloat *in_pixel; gfloat *out_pixel; gint n_pixels = result->width * result->height; gint width = result->width; GeglRectangle src_rect; gint total_pixels; gint i; tmp = gegl_buffer_new (result, babl_format ("RGBA float")); src_rect.x = result->x - op_area->left; src_rect.width = result->width + op_area->left + op_area->right; src_rect.y = result->y - op_area->top; src_rect.height = result->height + op_area->top + op_area->bottom; total_pixels = src_rect.height * src_rect.width; src_buf = g_slice_alloc (4 * total_pixels * sizeof (gfloat)); dst_buf = g_slice_alloc (4 * n_pixels * sizeof (gfloat)); gegl_buffer_copy (input, NULL, tmp, NULL); for (i = 0; i < o->repeat; i++) { gint x, y, n; x = result->x; y = result->y; n = 0; n_pixels = result->width * result->height; gegl_buffer_get (tmp, &src_rect, 1.0, babl_format ("RGBA float"), src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); in_pixel = src_buf + (src_rect.width + 1) * 4; out_pixel = dst_buf; while (n_pixels--) { gint b; if (gegl_random_double_range (o->seed, x, y, 0, n++, 0.0, 100.0) <= o->pct_random) { gint k = gegl_random_int_range (o->seed, x, y, 0, n++, 0, 9); for (b = 0; b < 4; b++) { switch (k) { case 0: out_pixel[b] = in_pixel[b - src_rect.width * 4 - 4]; break; case 1: out_pixel[b] = in_pixel[b - src_rect.width * 4]; break; case 2: out_pixel[b] = in_pixel[b - src_rect.width * 4 + 4]; break; case 3: out_pixel[b] = in_pixel[b - 4]; break; case 4: out_pixel[b] = in_pixel[b]; break; case 5: out_pixel[b] = in_pixel[b + 4]; break; case 6: out_pixel[b] = in_pixel[b + src_rect.width * 4 - 4]; break; case 7: out_pixel[b] = in_pixel[b + src_rect.width * 4]; break; case 8: out_pixel[b] = in_pixel[b + src_rect.width * 4 + 4]; break; } } } else { for (b = 0; b < 4; b++) { out_pixel[b] = in_pixel[b]; } } if (n_pixels % width == 0) in_pixel += 12; else in_pixel += 4; out_pixel += 4; x++; if (x >= result->x + result->width) { x = result->x; y++; } } gegl_buffer_set (tmp, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE); } gegl_buffer_copy (tmp, NULL, output, NULL); g_slice_free1 (4 * total_pixels * sizeof (gfloat), src_buf); g_slice_free1 (4 * n_pixels * sizeof (gfloat), dst_buf); return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation); GeglRectangle rect; GeglRectangle boundary = get_effective_area (operation); gfloat *src_buf; gfloat *dst_buf; gdouble **matrix; gchar *type; gint x, y; gdouble matrixsum = 0.0; type = "RGBA float"; matrix = g_new0 (gdouble*, MATRIX_SIZE); for (x=0; x < MATRIX_SIZE ;x++) matrix[x] = g_new0 (gdouble, MATRIX_SIZE); make_matrix (o, matrix); if (o->norm) normalize_o (o, matrix); for (x=0; x < MATRIX_SIZE; x++) for (y=0; y < MATRIX_SIZE; y++) matrixsum += fabs (matrix[x][y]); rect.x = result->x - op_area->left; rect.width = result->width + op_area->left + op_area->right; rect.y = result->y - op_area->top; rect.height = result->height + op_area->top + op_area->bottom; src_buf = g_new0 (gfloat, rect.width * rect.height * 4); dst_buf = g_new0 (gfloat, result->width * result->height * 4); gegl_buffer_get (input, &rect, 1.0, babl_format (type), src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); /*fill src_buf with wrap pixels if it is the case*/ if (o->div != 0) { for (y=result->y; y < result->height + result->y; y++) for (x=result->x; x < result->width + result->x; x++) convolve_pixel (src_buf, dst_buf, result, &rect, &boundary, matrix, o, input, x, y, matrixsum); gegl_buffer_set (output, result, 0, babl_format (type), dst_buf, GEGL_AUTO_ROWSTRIDE); } else gegl_buffer_set (output, &rect, 0, babl_format (type), src_buf, GEGL_AUTO_ROWSTRIDE); g_free (src_buf); g_free (dst_buf); return TRUE; }
static gboolean cl_process (GeglOperation *self, cl_mem in_tex, cl_mem out_tex, size_t global_worksize, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (self); gint num_sampling_points; gdouble *xs, *ys; gfloat *ysf = NULL; cl_mem cl_curve = NULL; cl_ulong cl_max_constant_size; cl_int cl_err = 0; num_sampling_points = o->sampling_points; if (!cl_data) { const char *kernel_name[] = {"cl_contrast_curve",NULL}; cl_data = gegl_cl_compile_and_build (contrast_curve_cl_source, kernel_name); } if (!cl_data) return TRUE; if (num_sampling_points > 0) { xs = g_new (gdouble, num_sampling_points); ys = g_new (gdouble, num_sampling_points); gegl_curve_calc_values (o->curve, 0.0, 1.0, num_sampling_points, xs, ys); g_free (xs); /*We need to downscale the array to pass it to the GPU*/ ysf = g_new (gfloat, num_sampling_points); copy_double_array_to_float_array (ys, ysf, num_sampling_points); g_free (ys); cl_err = gegl_clGetDeviceInfo (gegl_cl_get_device (), CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof (cl_ulong), &cl_max_constant_size, NULL); CL_CHECK; GEGL_NOTE (GEGL_DEBUG_OPENCL, "Max Constant Mem Size: %lu bytes", (unsigned long) cl_max_constant_size); if (sizeof (cl_float) * num_sampling_points < cl_max_constant_size) { cl_curve = gegl_clCreateBuffer (gegl_cl_get_context (), CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY, num_sampling_points * sizeof (cl_float), ysf, &cl_err); CL_CHECK; cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 0, sizeof (cl_mem), (void*) &in_tex); CL_CHECK; cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 1, sizeof (cl_mem), (void*) &out_tex); CL_CHECK; cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 2, sizeof (cl_mem), (void*) &cl_curve); CL_CHECK; cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 3, sizeof (gint), (void*) &num_sampling_points); CL_CHECK; cl_err = gegl_clEnqueueNDRangeKernel (gegl_cl_get_command_queue (), cl_data->kernel[0], 1, NULL, &global_worksize, NULL, 0, NULL, NULL); CL_CHECK; cl_err = gegl_clFinish (gegl_cl_get_command_queue ()); CL_CHECK; cl_err = gegl_clReleaseMemObject (cl_curve); CL_CHECK_ONLY (cl_err); } else { /*If the curve size doesn't fit constant memory is better to use CPU*/ GEGL_NOTE (GEGL_DEBUG_OPENCL, "Not enough constant memory for the curve"); g_free (ysf); return TRUE; } g_free (ysf); return FALSE; error: if (ysf) g_free (ysf); if (cl_curve) gegl_clReleaseMemObject (cl_curve); return TRUE; } else /*If the curve doesn't have a lookup table is better to use CPU*/ { GEGL_NOTE (GEGL_DEBUG_OPENCL, "Curve not suitable to be computed in the GPU"); return TRUE; } }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gint x = result->x; /* initial x */ gint y = result->y; /* and y coordinates */ gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat)); gfloat *out_pixel = dst_buf; GeglSampler *sampler = gegl_buffer_sampler_new (input, babl_format ("RGBA float"), o->sampler_type); gint n_pixels = result->width * result->height; GeglAbyssPolicy abyss = o->tileable ? GEGL_ABYSS_LOOP : GEGL_ABYSS_NONE; while (n_pixels--) { gdouble shift; gdouble coordsx; gdouble coordsy; gdouble lambda; gdouble angle_rad = o->angle / 180.0 * G_PI; gdouble nx = x * cos (angle_rad) + y * sin (angle_rad); switch (o->wave_type) { case GEGl_RIPPLE_WAVE_TYPE_SAWTOOTH: lambda = div (nx,o->period).rem - o->phi * o->period; if (lambda < 0) lambda += o->period; shift = o->amplitude * (fabs (((lambda / o->period) * 4) - 2) - 1); break; case GEGl_RIPPLE_WAVE_TYPE_SINE: default: shift = o->amplitude * sin (2.0 * G_PI * nx / o->period + 2.0 * G_PI * o->phi); break; } coordsx = x + shift * sin (angle_rad); coordsy = y + shift * cos (angle_rad); gegl_sampler_get (sampler, coordsx, coordsy, NULL, out_pixel, abyss); out_pixel += 4; /* update x and y coordinates */ x++; if (x>=result->x + result->width) { x=result->x; y++; } } gegl_buffer_set (output, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE); g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf); g_object_unref (sampler); return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); FILE *fp; pnm_struct img; GeglRectangle rect = {0,0,0,0}; gboolean ret = FALSE; fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb")); if (!fp) return FALSE; if (!ppm_load_read_header (fp, &img)) goto out; /* Allocating Array Size */ /* Should use g_try_malloc(), but this causes crashes elsewhere because the * error signalled by returning FALSE isn't properly acted upon. Therefore * g_malloc() is used here which aborts if the requested memory size can't be * allocated causing a controlled crash. */ img.data = (guchar*) g_malloc (img.numsamples * img.bpc); /* No-op without g_try_malloc(), see above. */ if (! img.data) { g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.numsamples * img.bpc)); goto out; } rect.height = img.height; rect.width = img.width; switch (img.bpc) { case 1: gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u8"), img.data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); break; case 2: gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u16"), img.data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); break; default: g_warning ("%s: Programmer stupidity error", G_STRLOC); } ppm_load_read_image (fp, &img); switch (img.bpc) { case 1: gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u8"), img.data, GEGL_AUTO_ROWSTRIDE); break; case 2: gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u16"), img.data, GEGL_AUTO_ROWSTRIDE); break; default: g_warning ("%s: Programmer stupidity error", G_STRLOC); } g_free (img.data); ret = TRUE; out: if (stdin != fp) fclose (fp); return ret; }
static gboolean process(GeglOperation *op, void *in_buf, void *out_buf, glong n_pixels, const GeglRectangle *roi) { #if 0 // precise computation gfloat *in = in_buf; gfloat *out = out_buf; gint i; gfloat gamma_value = GEGL_CHANT_PROPERTIES (op)->gamma_value; gfloat linear_value = GEGL_CHANT_PROPERTIES (op)->linear_value; for (i=0; i<n_pixels; i++) { gfloat a, b, c, g; if(linear_value<1.0) { g = gamma_value*(1.0-linear_value)/(1.0-gamma_value*linear_value); a = 1.0/(1.0+linear_value*(g-1)); b = linear_value*(g-1)*a; c = powf(a*linear_value+b, g)/linear_value; } else { a = b = g = 0.0; c = 1.0; } gint j; gfloat col; for (j=0; j<3; j++) { col = in[j]; if(col < linear_value) col = fminf(c*col, 1.0); else col = fminf(powf(a*col+b, g), 1.0); out[j] = col; } in += 3; out+= 3; } #else // table: // printf("gamma processing %d samples\n", n_pixels); guint16 *in = in_buf; guint8 *out = out_buf; gint i; gfloat gamma_value = GEGL_CHANT_PROPERTIES(op)->gamma_value; gfloat linear_value = GEGL_CHANT_PROPERTIES(op)->linear_value; guint8 table[0x10000]; gfloat a, b, c, g; if(linear_value < 1.0) { g = gamma_value * (1.0 - linear_value) / (1.0 - gamma_value * linear_value); a = 1.0 / (1.0 + linear_value * (g - 1)); b = linear_value * (g - 1) * a; c = powf(a * linear_value + b, g) / linear_value; } else { a = b = g = 0.0; c = 1.0; } for(int k = 0; k < 0x10000; k++) { gint32 tmp; if(k < 0x10000 * linear_value) tmp = MIN(c * k, 0xFFFF); else tmp = MIN(pow(a * k / 0x10000 + b, g) * 0x10000, 0xFFFF); table[k] = tmp >> 8; } for(i = 0; i < n_pixels; i++) { gint j; for(j = 0; j < 3; j++) out[2 - j] = table[in[j]]; in += 3; out += 4; } #endif return TRUE; }
static gboolean reinhard05_process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result) { const GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); const gint pix_stride = 4, /* RGBA */ RGB = 3; gfloat *lum, *pix; gfloat key, contrast, intensity, chrom = o->chromatic, chrom_comp = 1.0 - o->chromatic, light = o->light, light_comp = 1.0 - o->light; stats world_lin, world_log, channel [RGB], normalise; gint i, c; g_return_val_if_fail (operation, FALSE); g_return_val_if_fail (input, FALSE); g_return_val_if_fail (output, FALSE); g_return_val_if_fail (result, FALSE); g_return_val_if_fail (babl_format_get_n_components (babl_format (OUTPUT_FORMAT)) == pix_stride, FALSE); g_return_val_if_fail (chrom >= 0.0 && chrom <= 1.0, FALSE); g_return_val_if_fail (chrom_comp >= 0.0 && chrom_comp <= 1.0, FALSE); g_return_val_if_fail (light >= 0.0 && light <= 1.0, FALSE); g_return_val_if_fail (light_comp >= 0.0 && light_comp <= 1.0, FALSE); /* Obtain the pixel data */ lum = g_new (gfloat, result->width * result->height), gegl_buffer_get (input, 1.0, result, babl_format ("Y float"), lum, GEGL_AUTO_ROWSTRIDE); pix = g_new (gfloat, result->width * result->height * pix_stride); gegl_buffer_get (input, 1.0, result, babl_format (OUTPUT_FORMAT), pix, GEGL_AUTO_ROWSTRIDE); /* Collect the image stats, averages, etc */ reinhard05_stats_start (&world_lin); reinhard05_stats_start (&world_log); reinhard05_stats_start (&normalise); for (i = 0; i < RGB; ++i) { reinhard05_stats_start (channel + i); } for (i = 0; i < result->width * result->height; ++i) { reinhard05_stats_update (&world_lin, lum[i] ); reinhard05_stats_update (&world_log, logf (2.3e-5f + lum[i])); for (c = 0; c < RGB; ++c) { reinhard05_stats_update (channel + c, pix[i * pix_stride + c]); } } g_return_val_if_fail (world_lin.min >= 0.0, FALSE); reinhard05_stats_finish (&world_lin); reinhard05_stats_finish (&world_log); for (i = 0; i < RGB; ++i) { reinhard05_stats_finish (channel + i); } /* Calculate key parameters */ key = (logf (world_lin.max) - world_log.avg) / (logf (world_lin.max) - logf (2.3e-5f + world_lin.min)); contrast = 0.3 + 0.7 * powf (key, 1.4); intensity = expf (-o->brightness); g_return_val_if_fail (contrast >= 0.3 && contrast <= 1.0, FALSE); /* Apply the operator */ for (i = 0; i < result->width * result->height; ++i) { gfloat local, global, adapt; if (lum[i] == 0.0) continue; for (c = 0; c < RGB; ++c) { gfloat *_p = pix + i * pix_stride + c, p = *_p; local = chrom * p + chrom_comp * lum[i]; global = chrom * channel[c].avg + chrom_comp * world_lin.avg; adapt = light * local + light_comp * global; p /= p + powf (intensity * adapt, contrast); *_p = p; reinhard05_stats_update (&normalise, p); } } /* Normalise the pixel values */ reinhard05_stats_finish (&normalise); for (i = 0; i < result->width * result->height; ++i) { for (c = 0; c < pix_stride; ++c) { gfloat *p = pix + i * pix_stride + c; *p = (*p - normalise.min) / normalise.range; } } /* Cleanup and set the output */ gegl_buffer_set (output, result, babl_format (OUTPUT_FORMAT), pix, GEGL_AUTO_ROWSTRIDE); g_free (pix); g_free (lum); return TRUE; }
static cl_int cl_process (GeglOperation *operation, cl_mem in_tex, cl_mem out_tex, size_t global_worksize, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gfloat scale; gfloat radius0, radius1; gint roi_x, roi_y,x; gint midx, midy; GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input"); gfloat length = hypot (bounds->width, bounds->height)/2; gfloat rdiff; gfloat cost, sint; gfloat color[4]; scale = bounds->width / (1.0 * bounds->height); scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion); scale *= aspect_to_scale (o->squeeze); length = (bounds->width/2.0); if (scale > 1.0) length /= scale; gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color); for (x=0; x<3; x++) /* premultiply */ color[x] *= color[3]; radius0 = o->radius * (1.0-o->softness); radius1 = o->radius; rdiff = radius1-radius0; if (fabs (rdiff) < 0.0001) rdiff = 0.0001; midx = bounds->x + bounds->width * o->x; midy = bounds->y + bounds->height * o->y; roi_x = roi->x; roi_y = roi->y; /* constant for all pixels */ cost = cos(-o->rotation * (G_PI*2/360.0)); sint = sin(-o->rotation * (G_PI*2/360.0)); if (!cl_data) { const char *kernel_name[] = {"vignette_cl",NULL}; cl_data = gegl_cl_compile_and_build (kernel_source, kernel_name); } if (!cl_data) return 1; { const size_t gbl_size[2] = {roi->width, roi->height}; gint shape = o->shape; gfloat gamma = o->gamma; cl_int cl_err = 0; cl_float4 f_color; f_color.s[0] = color[0]; f_color.s[1] = color[1]; f_color.s[2] = color[2]; f_color.s[3] = color[3]; cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 0, sizeof(cl_mem), (void*)&in_tex); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 1, sizeof(cl_mem), (void*)&out_tex); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 2, sizeof(cl_float4),(void*)&f_color); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 3, sizeof(cl_float), (void*)&scale); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 4, sizeof(cl_float), (void*)&cost); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 5, sizeof(cl_float), (void*)&sint); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 6, sizeof(cl_int), (void*)&roi_x); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 7, sizeof(cl_int), (void*)&roi_y); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 8, sizeof(cl_int), (void*)&midx); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 9, sizeof(cl_int), (void*)&midy); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 10, sizeof(cl_int), (void*)&shape); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 11, sizeof(cl_float), (void*)&gamma); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 12, sizeof(cl_float), (void*)&length); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 13, sizeof(cl_float), (void*)&radius0); cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 14, sizeof(cl_float), (void*)&rdiff); if (cl_err != CL_SUCCESS) return cl_err; cl_err = gegl_clEnqueueNDRangeKernel(gegl_cl_get_command_queue (), cl_data->kernel[0], 2, NULL, gbl_size, NULL, 0, NULL, NULL); if (cl_err != CL_SUCCESS) return cl_err; } return CL_SUCCESS; }
static void calculate_bleed (GeglOperation *operation, GeglBuffer *input) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglRectangle rectA, rectB; GeglBufferIterator *iter; gfloat max_length = (gfloat) o->strength; gfloat threshold = o->threshold; GHashTable *bleed_table = o->chant_data; rectA = *gegl_operation_source_get_bounding_box (operation, "input"); rectA.width -= 3; rectB = rectA; rectB.x += 3; if (rectA.width <= 0) return; iter = gegl_buffer_iterator_new (input, &rectA, 0, babl_format ("RGBA float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, input, &rectB, 0, babl_format ("RGBA float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gint ix, iy; gfloat *pixelsA = (gfloat *)iter->data[0]; gfloat *pixelsB = (gfloat *)iter->data[1]; for (ix = 0; ix < iter->roi[0].width; ix++) for (iy = 0; iy < iter->roi[0].height; iy++) { gint idx = iy * iter->roi[0].width + ix * 4; if (threshold_exceeded (&pixelsA[idx], &pixelsB[idx], threshold)) { gint x = ix + iter->roi[0].x; gint y = iy + iter->roi[0].y; pair *k = g_new (pair, 1); gint *v = g_new (gint, 1); gint bleed_length = 1 + gegl_random_int_range (o->rand, x, y, 0, 0, 0, max_length); k->x = x; k->y = y; *v = bleed_length; g_hash_table_insert (bleed_table, k, v); } } } }
static gboolean process (GeglOperation *operation, void *in_buf, void *out_buf, glong n_pixels, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gfloat *in_pixel = in_buf; gfloat *out_pixel = out_buf; gfloat scale; gfloat radius0, radius1; gint x, y; gint midx, midy; GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input"); gfloat length = hypot (bounds->width, bounds->height)/2; gfloat rdiff; gfloat cost, sint; gfloat costy, sinty; gfloat color[4]; scale = bounds->width / (1.0 * bounds->height); scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion); scale *= aspect_to_scale (o->squeeze); length = (bounds->width/2.0); if (scale > 1.0) length /= scale; gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color); for (x=0; x<3; x++) /* premultiply */ color[x] *= color[3]; radius0 = o->radius * (1.0-o->softness); radius1 = o->radius; rdiff = radius1-radius0; if (fabs (rdiff) < 0.0001) rdiff = 0.0001; midx = bounds->x + bounds->width * o->x; midy = bounds->y + bounds->height * o->y; x = roi->x; y = roi->y; /* constant for all pixels */ cost = cos(-o->rotation * (G_PI*2/360.0)); sint = sin(-o->rotation * (G_PI*2/360.0)); /* constant per scanline */ sinty = sint * (y-midy) - midx; costy = cost * (y-midy) + midy; while (n_pixels--) { gfloat strength = 0.0; gfloat u, v; #if 0 u = cost * (x-midx) - sint * (y-midy) + midx; v = sint * (x-midx) + cost * (y-midy) + midy; /* optimized out of innerscanline loop */ #endif u = cost * (x-midx) - sinty; v = sint * (x-midx) + costy; if (length == 0.0) strength = 0.0; else { switch (o->shape) { case 0: /* circle */ strength = hypot ((u-midx) / scale, v-midy); break; case 1: /* square */ strength = MAX(ABS(u-midx) / scale, ABS(v-midy)); break; case 2: /* diamond */ strength = ABS(u-midx) / scale + ABS(v-midy); break; } strength /= length; strength = (strength-radius0) / rdiff; } if (strength<0.0) strength = 0.0; if (strength>1.0) strength = 1.0; if (o->gamma > 0.9999 && o->gamma < 2.0001) strength *= strength; /* fast path for default gamma */ else if (o->gamma != 1.0) strength = powf(strength, o->gamma); /* this gamma factor is * very expensive.. */ out_pixel[0]=in_pixel[0] * (1.0-strength) + color[0] * strength; out_pixel[1]=in_pixel[1] * (1.0-strength) + color[1] * strength; out_pixel[2]=in_pixel[2] * (1.0-strength) + color[2] * strength; out_pixel[3]=in_pixel[3] * (1.0-strength) + color[3] * strength; out_pixel += 4; in_pixel += 4; /* update x and y coordinates */ if (++x>=roi->x + roi->width) { x=roi->x; y++; sinty = sint * (y-midy) - midx; costy = cost * (y-midy) + midy; } } return TRUE; }
static int decode_frame (GeglOperation *operation, glong frame) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); Priv *p = (Priv*)o->chant_data; glong prevframe = p->prevframe; glong decodeframe; /*< frame to be requested decoded */ if (frame >= p->frames) { frame = p->frames - 1; } if (frame < 0) { frame = 0; } if (frame == prevframe) { return 0; } /* figure out which frame we should start decoding at */ if (frame == prevframe + 1) { decodeframe = prevframe + 1; } else { decodeframe = prev_keyframe (p, frame); if (prevframe > decodeframe && prevframe < frame) decodeframe = prevframe + 1; } if (decodeframe < prevframe) { /* seeking backwards, since it ffmpeg doesn't allow us,. we'll reload the file */ g_free (p->loadedfilename); p->loadedfilename = NULL; init (o); } while (decodeframe <= frame) { int got_picture = 0; do { int decoded_bytes; if (p->coded_bytes <= 0) { do { if (av_read_packet (p->ic, &p->pkt) < 0) { fprintf (stderr, "av_read_packet failed for %s\n", o->path); return -1; } } while (p->pkt.stream_index != p->video_stream); p->coded_bytes = p->pkt.size; p->coded_buf = p->pkt.data; } decoded_bytes = avcodec_decode_video2 (p->video_st->codec, p->lavc_frame, &got_picture, &p->pkt); if (decoded_bytes < 0) { fprintf (stderr, "avcodec_decode_video failed for %s\n", o->path); return -1; } p->coded_buf += decoded_bytes; p->coded_bytes -= decoded_bytes; } while (!got_picture); decodeframe++; } p->prevframe = frame; return 0; }
static gboolean process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglRectangle rect = {0,0,0,0}; jas_image_t *image; gint width, height, depth; gsize bpc; guchar *data = NULL; gboolean ret; int components[3]; jas_matrix_t *matrices[3] = {NULL, NULL, NULL}; gint i; gint row; gboolean b; gushort *ptr_s; guchar *ptr_b; image = NULL; width = height = depth = 0; if (!query_jp2 (o->path, &width, &height, &depth, &image)) return FALSE; rect.height = height; rect.width = width; switch (depth) { case 8: bpc = sizeof (guchar); break; case 16: bpc = sizeof (gushort); break; default: g_warning ("%s: Programmer stupidity error", G_STRLOC); return FALSE; } data = (guchar *) g_malloc (width * height * 3 * bpc); ptr_s = (gushort *) data; ptr_b = data; switch (depth) { case 16: gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u16"), data, GEGL_AUTO_ROWSTRIDE); break; case 8: default: gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u8"), data, GEGL_AUTO_ROWSTRIDE); } ret = FALSE; b = FALSE; do { components[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R)); components[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G)); components[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B)); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { g_warning (_("One or more of R, G, B components are missing " "from '%s'"), o->path); break; } if (jas_image_cmptsgnd (image, components[0]) || jas_image_cmptsgnd (image, components[1]) || jas_image_cmptsgnd (image, components[2])) { g_warning (_("One or more of R, G, B components have signed " "data in '%s'"), o->path); break; } for (i = 0; i < 3; i++) matrices[i] = jas_matrix_create(1, width); for (row = 0; row < height; row++) { gint plane, col; jas_seqent_t *jrow[3] = {NULL, NULL, NULL}; for (plane = 0; plane < 3; plane++) { int r = jas_image_readcmpt (image, components[plane], 0, row, width, 1, matrices[plane]); if (r) { g_warning (_("Error reading row %d component %d from '%s'"), row, plane, o->path); b = TRUE; break; } } if (b) break; for (plane = 0; plane < 3; plane++) jrow[plane] = jas_matrix_getref (matrices[plane], 0, 0); for (col = 0; col < width; col++) { switch (depth) { case 16: *ptr_s++ = (gushort) jrow[0][col]; *ptr_s++ = (gushort) jrow[1][col]; *ptr_s++ = (gushort) jrow[2][col]; break; case 8: default: *ptr_b++ = (guchar) jrow[0][col]; *ptr_b++ = (guchar) jrow[1][col]; *ptr_b++ = (guchar) jrow[2][col]; } } } if (b) break; switch (depth) { case 16: gegl_buffer_set (output, &rect, babl_format ("R'G'B' u16"), data, GEGL_AUTO_ROWSTRIDE); break; case 8: default: gegl_buffer_set (output, &rect, babl_format ("R'G'B' u8"), data, GEGL_AUTO_ROWSTRIDE); } ret = TRUE; } while (FALSE); /* structured goto */ for (i = 0; i < 3; i++) if (matrices[i]) jas_matrix_destroy (matrices[i]); if (data) g_free (data); if (image) jas_image_destroy (image); return ret; }
static gboolean process (GeglOperation *operation, void *out_buf, glong n_pixels, const GeglRectangle *roi, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gfloat *out_pixel = out_buf; gfloat color1[4]; gfloat color2[4]; gint x = roi->x; /* initial x */ gint y = roi->y; /* and y coordinates */ gegl_color_get_pixel (o->color1, babl_format ("RGBA float"), color1); gegl_color_get_pixel (o->color2, babl_format ("RGBA float"), color2); while (n_pixels--) { gint nx,ny; if ((x - o->x_offset) < 0) { nx = div (x - o->x_offset + 1, o->x).quot; } else { nx = div (x - o->x_offset, o->x).quot; } if ((y - o->y_offset) < 0) { ny = div (y - o->y_offset + 1, o->y).quot; } else { ny = div (y - o->y_offset, o->y).quot; } /* shift negative cell indices */ nx -= (x - o->x_offset) < 0 ? 1 : 0; ny -= (y - o->y_offset) < 0 ? 1 : 0; if ( (nx+ny) % 2 == 0) { out_pixel[0]=color1[0]; out_pixel[1]=color1[1]; out_pixel[2]=color1[2]; out_pixel[3]=color1[3]; } else { out_pixel[0]=color2[0]; out_pixel[1]=color2[1]; out_pixel[2]=color2[2]; out_pixel[3]=color2[3]; } out_pixel += 4; /* update x and y coordinates */ x++; if (x>=roi->x + roi->width) { x=roi->x; y++; } } return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); if (o->buffer) { GeglBuffer *output = GEGL_BUFFER (o->buffer); const Babl *in_format = gegl_buffer_get_format (input); const Babl *out_format = gegl_buffer_get_format (output); if (gegl_operation_use_opencl (operation) && gegl_cl_color_supported (in_format, out_format) == GEGL_CL_COLOR_CONVERT) { size_t size; gboolean err; cl_int cl_err = 0; GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output, result, out_format, GEGL_CL_BUFFER_WRITE); gint read = gegl_buffer_cl_iterator_add (i, input, result, out_format, GEGL_CL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_cl_color_babl (out_format, &size); GEGL_NOTE (GEGL_DEBUG_OPENCL, "write-buffer: " "%p %p %s %s {%d %d %d %d}", input, output, babl_get_name (in_format), babl_get_name (out_format), result->x, result->y, result->width, result->height); while (gegl_buffer_cl_iterator_next (i, &err)) { if (err) break; cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue (), i->tex[read], i->tex[0], 0, 0, i->size[0] * size, 0, NULL, NULL); if (cl_err != CL_SUCCESS) { GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", gegl_cl_errstring (cl_err)); break; } } if (cl_err || err) gegl_buffer_copy (input, result, output, result); } else gegl_buffer_copy (input, result, output, result); gegl_buffer_flush (output); } return TRUE; }