static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglProperties *o = GEGL_PROPERTIES (operation); Transform transform; const Babl *format_io; GeglSampler *sampler; gint factor = 1 << level; GeglBufferIterator *it; GeglRectangle in_rect = *gegl_operation_source_get_bounding_box (operation, "input"); GeglMatrix2 scale_matrix; GeglMatrix2 *scale = NULL; gint sampler_type = o->sampler_type; level = 0; factor = 1; prepare_transform2 (&transform, operation, level); if (level) sampler_type = GEGL_SAMPLER_NEAREST; format_io = babl_format ("RaGaBaA float"); { /* XXX: panorama projection needs to sample from a higher resolution than * its output to yield good results. This affects which level should * be rendered for source nodes.. */ gint sample_level = level - 3; if (sample_level < 0) sample_level = 0; sampler = gegl_buffer_sampler_new_at_level (input, format_io, sampler_type, sample_level); } if (sampler_type == GEGL_SAMPLER_NOHALO || sampler_type == GEGL_SAMPLER_LOHALO) scale = &scale_matrix; { float ud = ((1.0/transform.width)*factor); float vd = ((1.0/transform.height)*factor); it = gegl_buffer_iterator_new (output, result, level, format_io, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (it)) { gint i; gint n_pixels = it->length; gint x = it->roi->x; /* initial x */ gint y = it->roi->y; /* and y coordinates */ float u0 = (((x*factor)/transform.width) - transform.xoffset); float u, v; float *out = it->data[0]; u = u0; v = ((y*factor/transform.height) - 0.5); if (scale) { for (i=0; i<n_pixels; i++) { float cx, cy; #define gegl_unmap(xx,yy,ud,vd) { \ float rx, ry; \ transform.xy2ll (&transform, xx, yy, &rx, &ry); \ ud = rx;vd = ry;} gegl_sampler_compute_scale (scale_matrix, u, v); gegl_unmap(u,v, cx, cy); #undef gegl_unmap gegl_sampler_get (sampler, cx * in_rect.width, cy * in_rect.height, scale, out, GEGL_ABYSS_LOOP); out += 4; /* update x, y and u,v coordinates */ x++; u+=ud; if (x >= (it->roi->x + it->roi->width)) { x = it->roi->x; y++; u = u0; v += vd; } } } else { for (i=0; i<n_pixels; i++) { float cx, cy; transform.xy2ll (&transform, u, v, &cx, &cy); gegl_sampler_get (sampler, cx * in_rect.width, cy * in_rect.height, scale, out, GEGL_ABYSS_LOOP); out += 4; /* update x, y and u,v coordinates */ x++; u+=ud; if (x >= (it->roi->x + it->roi->width)) { x = it->roi->x; u = u0; y++; v += vd; } } } } } g_object_unref (sampler); #if 0 { float t; float lat0 = 0; float lon0 = 0; float lat1 = 0.5; float lon1 = 0.5; int i = 0; guchar pixel[4] = {255,0,0,255}; for (t = 0; t < 1.0; t+=0.01, i++) { float lat = lat0 * (1.0 - t) + lat1 * t; float lon = lon0 * (1.0 - t) + lon1 * t; float x, y; float xx, yy; GeglRectangle prect = {0,0,1,1}; ll2xy (&transform, lon, lat, &x, &y); x += xoffset; y += 0.5; x *= width; y *= height; prect.x = floor (x); prect.y = floor (y); prect.width = 1; prect.height = 1; gegl_buffer_set (output, &prect, 0, babl_format ("R'G'B' u8"), pixel, 8); } } #endif return TRUE; }
int safssi_stdat(struct latlon gpos, fmproj myproj, osihdf *safssi, safssi_data *ssi) { int dx, dy, i, j, k, l, m; int nodata = 1; struct dto timeid; struct xy xyp; fmposxy tgxy; fmindxy tgin; fmposll tgll; fmimage rim; /* * Convert from image header to useable data structures, first * satellite id. */ sprintf((*ssi).source,"%s", safssi->h.source); /* * The UCS info is converted */ rim.Ax = safssi->h.Ax; rim.Ay = safssi->h.Ay; rim.Bx = safssi->h.Bx; rim.By = safssi->h.By; rim.iw = safssi->h.iw; rim.ih = safssi->h.ih; (*ssi).nav.Ax = rim.Ax; (*ssi).nav.Ay = rim.Ay; /* * Set UNIX time for product */ timeid.mi = safssi->h.minute; timeid.ho = safssi->h.hour; timeid.dd = safssi->h.day; timeid.mm = safssi->h.month; timeid.yy = safssi->h.year; (*ssi).vtime = dto2unixtime(timeid);; /* * Get UCS position of the requested geographical position within the * image. */ tgll.lat = (double) gpos.lat; tgll.lon = (double) gpos.lon; tgxy = ll2xy(tgll, myproj) ; tgin = xy2ind(rim, tgxy); if (tgin.x < 0 || tgin.y < 0) return(3); (*ssi).nav.Bx = (float) tgxy.x; (*ssi).nav.By = (float) tgxy.y; /* * Check bounding box size, these parameters are set by the init * function... */ if ((*ssi).nav.iw%2 == 0 || (*ssi).nav.ih%2 == 0) { error("avhrr_stdat","area required must be odd\n"); return(2); } /* * Collect the actual data, l is used for pixel count within the * actual image, and k within the storage tile. */ dx = (int) floorf((float) (*ssi).nav.iw/2.); dy = (int) floorf((float) (*ssi).nav.ih/2.); k = 0; for (i=(tgin.y-dy); i<=(tgin.y+dy); i++) { for (j=(tgin.x-dx); j<=(tgin.x+dx); j++) { /* * Check if within image coverage... */ if (i < 0 || j < 0 || i >= rim.ih || j >= rim.iw) continue; /* * Navigation is performed in 2D while data is stored in 1D... */ l = ivec(j,i,rim.iw); /* * Collect data... */ (*ssi).data[k] = ((float *) safssi->d[0].data)[l]; (*ssi).qflg[k] = ((unsigned short *) safssi->d[1].data)[l]; k++; } } return(0); }