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;
}
Example #2
0
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);
}