Esempio n. 1
0
static void
waves (GimpDrawable *drawable)
{
  GimpPixelRgn  srcPr, dstPr;
  guchar       *src, *dst;
  guint         width, height, bpp, has_alpha;

  width     = drawable->width;
  height    = drawable->height;
  bpp       = drawable->bpp;
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  src = g_new (guchar, width * height * bpp);
  dst = g_new (guchar, width * height * bpp);
  gimp_pixel_rgn_init (&srcPr, drawable, 0, 0, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dstPr, drawable, 0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_get_rect (&srcPr, src, 0, 0, width, height);

  wave (src, dst, width, height, bpp, has_alpha,
        width / 2.0, height / 2.0,
        wvals.amplitude, wvals.wavelength, wvals.phase,
        wvals.type == MODE_SMEAR, wvals.reflective, TRUE);
  gimp_pixel_rgn_set_rect (&dstPr, dst, 0, 0, width, height);

  g_free (src);
  g_free (dst);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, 0, 0, width, height);

  gimp_displays_flush ();
}
Esempio n. 2
0
/*
   This function operates on PixelArea, whose width and height are
   multiply of pixel width, and less than the tile size (to enhance
   its speed).

   If any coordinates of mask boundary is not multiply of pixel width
   (e.g.  x1 % pixelwidth != 0), operates on the region whose width
   or height is the remainder.
 */
static void
pixelize_small (GimpDrawable *drawable,
                gint          pixelwidth,
                gint          pixelheight,
                gint          tile_width,
                gint          tile_height)
{
  GimpPixelRgn src_rgn, dest_rgn;
  gint         bpp, has_alpha;
  gint         x1, y1, x2, y2;
  gint         progress, max_progress;

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE);

  /* Initialize progress */
  progress = 0;
  max_progress = (x2 - x1) * (y2 - y1);

  bpp = drawable->bpp;
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  area.width  = (tile_width  / pixelwidth)  * pixelwidth;
  area.height = (tile_height / pixelheight) * pixelheight;
  area.data= g_new (guchar, (glong) bpp * area.width * area.height);

  for (area.y = y1; area.y < y2;
       area.y += area.height - (area.y % area.height))
    {
      area.h = area.height - (area.y % area.height);
      area.h = MIN (area.h, y2 - area.y);

      for (area.x = x1; area.x < x2;
           area.x += area.width - (area.x % area.width))
        {
          area.w = area.width - (area.x % area.width);
          area.w = MIN(area.w, x2 - area.x);

          gimp_pixel_rgn_get_rect (&src_rgn, area.data,
                                   area.x, area.y, area.w, area.h);

          pixelize_sub (pixelwidth, pixelheight, bpp, has_alpha);

          gimp_pixel_rgn_set_rect (&dest_rgn, area.data,
                                   area.x, area.y, area.w, area.h);

          /* Update progress */
          progress += area.w * area.h;
          gimp_progress_update ((double) progress / (double) max_progress);
      }
    }

  g_free(area.data);

  /*  update the pixelized region  */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));
}
Esempio n. 3
0
/*
 * sendBMPToGIMP
 *
 * Take the captured data and send it across
 * to GIMP.
 */
static void
sendBMPToGimp(HBITMAP hBMP, HDC hDC, RECT rect)
{
  int		width, height;
  int		imageType, layerType;
  gint32	image_id;
  gint32	layer_id;
  GimpPixelRgn	pixel_rgn;
  GimpDrawable    *drawable;

  /* Our width and height */
  width = (rect.right - rect.left);
  height = (rect.bottom - rect.top);

  /* Check that we got the memory */
  if (!capBytes) {
    g_message (_("No data captured"));
    return;
  }

  /* Flip the red and blue bytes */
  flipRedAndBlueBytes(width, height);

  /* Set up the image and layer types */
  imageType = GIMP_RGB;
  layerType = GIMP_RGB_IMAGE;

  /* Create the GIMP image and layers */
  image_id = gimp_image_new(width, height, imageType);
  layer_id = gimp_layer_new(image_id, _("Background"),
			    ROUND4(width), height,
			    layerType, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer(image_id, layer_id, -1, 0);

  /* Get our drawable */
  drawable = gimp_drawable_get(layer_id);

  gimp_tile_cache_size(ROUND4(width) * gimp_tile_height() * 3);

  /* Initialize a pixel region for writing to the image */
  gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0,
		      ROUND4(width), height, TRUE, FALSE);

  gimp_pixel_rgn_set_rect(&pixel_rgn, (guchar *) capBytes,
			  0, 0, ROUND4(width), height);

  /* HB: update data BEFORE size change */
  gimp_drawable_flush(drawable);
  /* Now resize the layer down to the correct size if necessary. */
  if (width != ROUND4(width)) {
    gimp_layer_resize (layer_id, width, height, 0, 0);
    gimp_image_resize (image_id, width, height, 0, 0);
  }
  /* Finish up */
  gimp_drawable_detach(drawable);
  gimp_display_new (image_id);

  return;
}
Esempio n. 4
0
gint32 execute_plugin(GimpDrawable* d, const char *nome, param_type *p)
{
//	gint i;
	guchar *img, *org;
	gint x,y,x2,y2,w,h;
//	guchar *work;
	GimpPixelRgn region, rgn_org;
	gint bpp = d->bpp;

	gimp_drawable_mask_bounds(d->drawable_id, &x, &y, &x2, &y2);
	w = x2 - x;
	h = y2 - y;

	img = malloc(w * h * bpp);
	org = malloc(w * h * bpp);
//	work = malloc(d.width * d.height * bpp);

	gimp_pixel_rgn_init(&region, d, x, y, w, h, TRUE, TRUE);
	//este é buffer para gravar a imagem modificada.
	gimp_pixel_rgn_init(&rgn_org, d, x, y, w, h, FALSE, FALSE);
	// Esta é a imagem em si 

	gimp_pixel_rgn_get_rect(&region, img, x, y, w, h);
	gimp_pixel_rgn_get_rect(&rgn_org, org, x, y, w, h);

	switch (*nome) {
		case 'S':
			super_grow(p, org, img, w, h, bpp);
			break;
		case 'G':
			memcpy(img, org, w * h * bpp);
			grow(p, org, img, w, h, bpp);
			break;
		case 'A':
			find_iso(p, org, img, w, h, bpp);
			break;
		default:
			make_height_field(p, org, img, w, h, bpp);
			break;
			
	}

	gimp_pixel_rgn_set_rect(&region, img, x, y, w, h);

	/* finish the process */
	gimp_drawable_flush (d);
	gimp_drawable_merge_shadow (d->drawable_id, TRUE);
	gimp_drawable_update (d->drawable_id, x, y, w, h);
	gimp_displays_flush();
	gimp_drawable_detach(d);

	free(img);
	free(org);

	return GIMP_PDB_SUCCESS;	
}
Esempio n. 5
0
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_drawable_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_add_layer (image_id, preview_id, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
Esempio n. 6
0
// Combine wavelets with latest FFT result and show output in the preview widget
void wavelet_preview(PluginData *pd)
{
	int x, y, w, h;
	gimp_preview_get_position (GIMP_PREVIEW(pd->preview), &x, &y);
	gimp_preview_get_size (GIMP_PREVIEW(pd->preview), &w, &h);
	gimp_pixel_rgn_init (&pd->region, pd->drawable, 0, 0, pd->image_width, pd->image_height, FALSE, TRUE);
	wavelet_apply(pd, x, y, w, h);
	
	gimp_pixel_rgn_set_rect(&pd->region, pd->img_pixels, x, y, w, h);
	gimp_drawable_preview_draw_region(GIMP_DRAWABLE_PREVIEW(pd->preview), &pd->region);
}
Esempio n. 7
0
void
focusblur_fft_buffer_draw (FblurFftBuffer *fft)
{
  GimpDrawablePreview *preview;
  gboolean             dirty;
  guint8              *data;
  GimpPixelRgn         pr;

  if (! fft->source.preview)
    {
      preview = NULL;
      dirty = TRUE;
      data = fft->source.data;
    }
  else
    {
      preview = GIMP_DRAWABLE_PREVIEW (fft->source.preview);
      g_assert (preview != NULL);

      dirty = FALSE;
      data = fft->source.data_preview;
    }

  g_assert (data != NULL);

  gimp_pixel_rgn_init (&pr, fft->source.drawable,
                       fft->source.x1, fft->source.y1,
                       fft->source.width, fft->source.height, dirty, TRUE);
  gimp_pixel_rgn_set_rect (&pr, data,
                           fft->source.x1, fft->source.y1,
                           fft->source.width, fft->source.height);

  if (! preview)
    {
      gimp_drawable_flush (fft->source.drawable);
      gimp_drawable_merge_shadow (fft->source.drawable->drawable_id, TRUE);
      gimp_drawable_update (fft->source.drawable->drawable_id,
                            fft->source.x1, fft->source.y1,
                            fft->source.width, fft->source.height);

      /* this buffer has been dirty */
      focusblur_fft_buffer_clear_source (fft);
    }
  else
    {
      gimp_drawable_preview_draw_region (preview, &pr);

    }
}
Esempio n. 8
0
/* Draw the hole at the specified position */
static void
draw_hole_rgb (GimpDrawable *drw,
               gint          x,
               gint          y,
               gint          width,
               gint          height,
               guchar       *hole)
{
  GimpPixelRgn    rgn;
  guchar         *data;
  gint            tile_height = gimp_tile_height ();
  gint            i, j, scan_lines;
  gint            d_width = gimp_drawable_width (drw->drawable_id);
  gint            length;

  if ((width <= 0) || (height <= 0))
    return;
  if ((x+width <= 0) || (x >= d_width))
    return;
  length = width;   /* Check that we dont draw past the image */
  if ((x+length) >= d_width)
    length = d_width-x;

  data = g_new (guchar, length * tile_height * drw->bpp);

  gimp_pixel_rgn_init (&rgn, drw, x, y, length, height, TRUE, FALSE);

  i = 0;
  while (i < height)
    {
      scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
      if (length == width)
        {
          memcpy (data, hole + 3*width*i, width*scan_lines*3);
        }
      else  /* We have to do some clipping */
        {
          for (j = 0; j < scan_lines; j++)
            memcpy (data + j*length*3, hole + (i+j)*width*3, length*3);
        }
      gimp_pixel_rgn_set_rect (&rgn, data, x, y+i, length, scan_lines);

      i += scan_lines;
    }

  g_free (data);
}
Esempio n. 9
0
static gboolean
file_vtf_load_layer (Vtf::HiresImageResource *vres, gint32 image, gint16 frame)
{
    uint8_t *rgba = vres->getImageRGBA(0, frame, 0, 0);
    g_return_val_if_fail (rgba != NULL, FALSE);

    gchar *name = g_strdup_printf ("Frame %d", frame);
    gint32 layer = gimp_layer_new (image, name, vres->width (), vres->height(),
                                   GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
    gimp_image_insert_layer (image, layer, -1, frame);
    g_free (name);

    GimpPixelRgn pixel_rgn;
    GimpDrawable *drawable = gimp_drawable_get (layer);
    gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width,
                         drawable->height, TRUE, FALSE);
    gimp_pixel_rgn_set_rect (&pixel_rgn, rgba, 0, 0, drawable->width,
                             drawable->height);
    gimp_drawable_detach (drawable);

    return TRUE;
}
Esempio n. 10
0
static void
despeckle (void)
{
  GimpPixelRgn  src_rgn;        /* Source image region */
  GimpPixelRgn  dst_rgn;
  guchar       *src;
  guchar       *dst;
  gint          img_bpp;
  gint          x, y;
  gint          width, height;

  img_bpp = gimp_drawable_bpp (drawable->drawable_id);

  if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                      &x, &y, &width, &height))
    return;

  gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dst_rgn, drawable, x, y, width, height, TRUE, TRUE);

  src = g_new (guchar, width * height * img_bpp);
  dst = g_new (guchar, width * height * img_bpp);

  gimp_pixel_rgn_get_rect (&src_rgn, src, x, y, width, height);

  despeckle_median (src, dst, width, height, img_bpp, despeckle_radius, FALSE);

  gimp_pixel_rgn_set_rect (&dst_rgn, dst, x, y, width, height);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x, y, width, height);

  g_free (dst);
  g_free (src);
}
Esempio n. 11
0
gint32
xjpg_load_layer (const char    *filename,
                 gint32         image_id,
                 int            image_type,
                 char          *layer_name,
                 gdouble        layer_opacity,
                 GimpLayerModeEffects     layer_mode
	    )
{
  GimpPixelRgn l_pixel_rgn;
  GimpDrawable *l_drawable;
  gint32     l_layer_id;
  GimpImageType  l_layer_type;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  FILE *infile;
  guchar *l_buf;
  guchar **l_rowbuf;
  int l_tile_height;
  int l_scanlines;
  int l_idx, l_start, l_end;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  l_layer_type = GIMP_GRAY_IMAGE;

  if ((infile = g_fopen (filename, "rb")) == NULL)
  {
      g_warning ("can't open \"%s\"\n", filename);
      return -1;
  }


  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
  {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
	fclose (infile);

      g_printerr ("XJT: JPEG load error\n");
      return -1;
  }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header (&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */
  /* temporary buffer */
  l_tile_height = gimp_tile_height ();
  l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components);
  l_rowbuf = g_new (guchar*, l_tile_height);

  for (l_idx = 0; l_idx < l_tile_height; l_idx++)
  {
    l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx;
  }

  /* Check jpeg file for layer type */
  switch (cinfo.output_components)
    {
    case 1:
      l_layer_type = GIMP_GRAY_IMAGE;
      break;
    case 3:
      l_layer_type = GIMP_RGB_IMAGE;
      break;
    default:
      g_printerr ("XJT: cant load layer %s (type is not GRAY and not RGB)\n", filename);
      fclose (infile);
      return -1;
    }


  l_layer_id = gimp_layer_new (image_id, layer_name,
			     cinfo.output_width,
			     cinfo.output_height,
			     l_layer_type,
			     layer_opacity,
			     layer_mode);
  if(l_layer_id < 0)
  {
      g_printerr ("XJT: cant create new layer\n");
      fclose (infile);
      return -1;
  }

  l_drawable = gimp_drawable_get (l_layer_id);
  gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE);

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
  {
      l_start = cinfo.output_scanline;
      l_end = cinfo.output_scanline + l_tile_height;
      l_end = MIN (l_end, cinfo.output_height);
      l_scanlines = l_end - l_start;

      for (l_idx = 0; l_idx < l_scanlines; l_idx++)
      {
	jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1);
      }

      gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_buf, 0, l_start, l_drawable->width, l_scanlines);

      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
  }
  gimp_progress_update (1.0);

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (l_rowbuf);
  g_free (l_buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  return (l_layer_id);

}	/* end xjpg_load_layer */
Esempio n. 12
0
gint
xjpg_load_layer_alpha (const char *filename,
                       gint32      image_id,
                       gint32      layer_id)
{
  GimpPixelRgn l_pixel_rgn;
  GimpDrawable *l_drawable;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  FILE *infile;
  guchar *l_buf;
  guchar *l_dstbuf;
  guchar **l_rowbuf;
  int l_tile_height;
  int l_scanlines;
  int l_idx, l_start, l_end;
  int l_alpha_offset;
  guchar *l_buf_ptr;
  guchar *l_dstbuf_ptr;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  /* add alpha channel */
  gimp_layer_add_alpha (layer_id);

  if ((infile = g_fopen (filename, "rb")) == NULL)
  {
      /* No alpha found, thats OK, use full opaque alpha channel
       * (there is no need not store alpha channels on full opaque channels)
       * (fixme: if filename exists but is not readable
       *         we should return -1 to indicate an error
       */
      return 0;  /* OK */
  }

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
  {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
	fclose (infile);

      g_printerr ("XJT: JPEG alpha load error\n");
      return -1;
  }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header (&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */
  /* temporary buffer (for read in jpeg lines) */
  l_tile_height = gimp_tile_height ();
  l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components);
  l_rowbuf = g_new (guchar*, l_tile_height);

  for (l_idx = 0; l_idx < l_tile_height; l_idx++)
  {
    l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx;
  }

  l_drawable = gimp_drawable_get (layer_id);
  if(l_drawable == NULL)
  {
    g_printerr ("XJT: gimp_drawable_get failed on layer id %d\n", (int)layer_id);
    fclose(infile);
    return -1;
  }

  /* Check if jpeg file can be used as alpha channel
   */
  if((cinfo.output_components != 1) ||
     (cinfo.output_width  != l_drawable->width) ||
     (cinfo.output_height != l_drawable->height))
  {
     g_printerr ("XJT: cant load %s as alpha channel\n", filename);
     fclose (infile);
     return -1;
  }

  /* buffer to read in the layer and merge with the alpha from jpeg file */
  l_dstbuf = g_new (guchar, l_tile_height * l_drawable->width * l_drawable->bpp);

  gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE);
  l_alpha_offset = l_drawable->bpp -1;

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
  {
      l_start = cinfo.output_scanline;
      l_end = cinfo.output_scanline + l_tile_height;
      l_end = MIN (l_end, cinfo.output_height);
      l_scanlines = l_end - l_start;

      for (l_idx = 0; l_idx < l_scanlines; l_idx++)
      {
	jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1);
      }

      gimp_pixel_rgn_get_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines);

      /* copy the loaded jpeg data (from buf) to the layers alpha channel data */
      l_idx = l_tile_height * l_drawable->width;
      l_buf_ptr = l_buf;
      l_dstbuf_ptr = l_dstbuf;
      while(l_idx--)
      {
         l_dstbuf_ptr  += l_alpha_offset;
         *l_dstbuf_ptr++ = *l_buf_ptr++;
      }

      gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines);

      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
  }
  gimp_progress_update (1.0);

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (l_rowbuf);
  g_free (l_buf);
  g_free (l_dstbuf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */


  return (0);  /* OK */

}	/* xjpg_load_layer_alpha */
Esempio n. 13
0
static void
c2g_region (GimpPixelRgn *srcPR,
                GimpPixelRgn *destPR,
                gint          bytes, /* Bytes per pixel */
                gdouble       radius,
                gdouble       amount_p,
                gdouble       gamma_p,
                gint          x1,    /* Corners of subregion */
                gint          x2,
                gint          y1,
                gint          y2,
                gboolean      show_progress)
{
  guchar  *src;
  guchar  *dest;
  guchar *bigsrc;
  guchar *bigdest;
  guchar *tmpdest;
 
  gint     width   = x2 - x1;
  gint     height  = y2 - y1;
  gdouble *cmatrix = NULL;
  gint     cmatrix_length;
  gdouble *ctable;
  gint     row, col, idx;
  gint w = c2g_params.radius+10;

  gdouble amount = c2g_params.amount;
  gdouble gamma = c2g_params.gamma;
    
  if (show_progress)
    gimp_progress_init (_("Blurring..."));
  
  iir_init(c2g_params.radius);

  /* allocate buffers */
  src  = g_new (guchar, MAX (width, height) * bytes);
  dest = g_new (guchar, MAX (width, height) * bytes);
  iir.p = g_new(gdouble, MAX (width, height)+2*w);

 
  bigsrc = g_new(guchar, width * height * bytes);
  bigdest = g_new(guchar, width * height * bytes);
  tmpdest = g_new(guchar, width * height * bytes);

  if (show_progress)
    gimp_progress_init (_("Colour converting..."));
  
  // 1. Calculate Nayatani Grey and Blur in LAB
  gimp_pixel_rgn_get_rect (srcPR, bigsrc, x1, y1, width, height);
  extract_lab(bigsrc, bytes, width * height, bigdest);
  nayatani(bigdest,bytes,width * height, bigdest);
  gimp_pixel_rgn_set_rect (destPR, bigdest, x1, y1, width, height);

  // 2. Make a blur of Grey LAB
  for (row = 0, idx=0; row < height; row++, idx+=width)
    {
      gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes);   
      gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width);
    }

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes);
      gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height);

      if (show_progress && col % 8 == 0)
        gimp_progress_update ((gdouble) col / (3 * width) + 0.33);
    }

  // 3. Convert grey and blur back to RGB.
  compose_lab(bigdest, width * height, bytes, bigdest); // bigdest=greyRGB
  gimp_pixel_rgn_get_rect (destPR, bigsrc, x1, y1, width, height);
  compose_lab(bigsrc, width * height, bytes, bigsrc); // bigsrc= blurgreyRGB

  // 4. Blur Colour RGB and write into destPR
  gimp_pixel_rgn_get_rect (srcPR, tmpdest, x1, y1, width, height);
  gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height);

  for (row = 0, idx=0; row < height; row++, idx+=width)
    {
      gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes);   
      gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width);
    }

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes);
      gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height);

      if (show_progress && col % 8 == 0)
        gimp_progress_update ((gdouble) col / (3 * width) + 0.33);
    }

  // destPR = blur colour RGB
  chromaunsharp( srcPR, destPR, bigdest, bigsrc, bytes, x1, y1, width, height, amount, gamma, tmpdest );
  compose_lab(tmpdest, width * height, bytes, tmpdest); // tmpdest has unsharp
  gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height);
  

  if (show_progress)
    gimp_progress_update (0.0);

  g_free (bigsrc);
  g_free (bigdest);
  g_free (tmpdest);
  g_free (iir.p);
  g_free (dest);
  g_free (src);
  
}
Esempio n. 14
0
gint32
load_djvu (const gchar * filename, 
          GimpRunMode runmode, 
          gboolean preview)

{
  
  GimpPixelRgn rgn_in;
  GimpDrawable *drawable;
  gint32 volatile image_ID;
  gint32 layer_ID;
  int x1, y1, x2, y2, width, height;
   unsigned char *src = NULL;
  int file_length;



ctx = ddjvu_context_create("gimp");
//
doc = ddjvu_document_create_by_filename(ctx,filename, TRUE);



while (! ddjvu_document_decoding_done(doc))
    handle(TRUE);
  




  i = ddjvu_document_get_pagenum(doc);
  dialog( &pageno ,i);
//processing the page
  
page = ddjvu_page_create_by_pageno(doc, pageno-1);
while (! ddjvu_page_decoding_done(page))
    handle(TRUE);

if (ddjvu_page_decoding_error(page))
{
 fprintf(stderr,"unexpected error ");
 exit(10);
}

// ddjvu variables

  ddjvu_rect_t prect;
  ddjvu_rect_t rrect;
  ddjvu_format_style_t style;
  ddjvu_render_mode_t mode;
  ddjvu_format_t *fmt;
  int iw = ddjvu_page_get_width(page);
  int ih = ddjvu_page_get_height(page);
  int dpi = ddjvu_page_get_resolution(page);
  ddjvu_page_type_t type = ddjvu_page_get_type(page);
  char *image = 0;
  int rowsize;

//end of ddjvu variables
style= DDJVU_FORMAT_RGB24;
mode=DDJVU_RENDER_COLOR;
fmt = ddjvu_format_create(style, 0, 0);
ddjvu_format_set_row_order(fmt, 1);

      prect.w = iw;
      prect.h = ih;

       prect.x = 0;
       prect.y = 0;

       flag_scale=150;

     prect.w = (unsigned int) (iw * flag_scale) / dpi;
     prect.h = (unsigned int) (ih * flag_scale) / dpi;
       
      rrect = prect;

 rowsize = (rrect.w *3);
 image = (char*)malloc(rowsize * rrect.h);
  
//generating page
ddjvu_page_render(page, mode, &prect, &rrect, fmt, rowsize, image);

ddjvu_page_release(page);
char *s =image;
  /* create output image */

  width = prect.w;
  height =  prect.h;
  x1 = 0;
  y1 = 0;
  x2 = prect.w;
  y2 = prect.h;


  image_ID = gimp_image_new (width, height, GIMP_RGB);
  layer_ID = gimp_layer_new (image_ID, _("Background"),
			     width, height, GIMP_RGB, 100, GIMP_NORMAL_MODE);
  gimp_image_add_layer (image_ID, layer_ID, 0);
  drawable = gimp_drawable_get (layer_ID);	// initializes the drawable     
  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
  gimp_pixel_rgn_init (&rgn_in, drawable, x1, y1,
		       x2 - x1, y2 - y1, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&rgn_in,  image, 0, 0, width, height);
      //g_free (buf);
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1);
  gimp_image_set_filename (image_ID, filename);
  return image_ID;
  image =NULL;
 

//not handling any error
if (doc)
    ddjvu_document_release(doc);
  if (ctx)
    ddjvu_context_release(ctx);
    
}
Esempio n. 15
0
static inline void
filter (void)
{
  static void (* overlap)(guchar *, const guchar *);
  GimpPixelRgn  src;
  GimpPixelRgn  dst;
  GimpRGB       color;
  guchar     pixel[4];
  gint       division_x;
  gint       division_y;
  gint       offset_x;
  gint       offset_y;
  Tile      *tiles;
  gint       numof_tiles;
  Tile      *t;
  gint       i;
  gint       x;
  gint       y;
  gint       move_max_pixels;
  gint       clear_x0;
  gint       clear_y0;
  gint       clear_x1;
  gint       clear_y1;
  gint       clear_width;
  gint       clear_height;
  guchar    *pixels;
  guchar    *buffer;
  gint       dindex;
  gint       sindex;
  gint       px, py;
  GRand     *gr;

  gr = g_rand_new ();

  /* INITIALIZE */
  gimp_pixel_rgn_init (&src, p.drawable, 0, 0,
                       p.drawable->width, p.drawable->height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dst, p.drawable, 0, 0,
                       p.drawable->width, p.drawable->height, TRUE, TRUE);
  pixels = g_new (guchar,
                  p.drawable->bpp * p.drawable->width * p.drawable->height);
  buffer = g_new (guchar,
                  p.drawable->bpp * p.params.tile_width * p.params.tile_height);

  overlap = p.drawable_has_alpha ? overlap_RGBA : overlap_RGB;

  gimp_progress_init (_("Paper Tile"));

  gimp_drawable_mask_bounds (p.drawable->drawable_id,
                             &p.selection.x0, &p.selection.y0,
                             &p.selection.x1, &p.selection.y1);
  p.selection.width  = p.selection.x1 - p.selection.x0;
  p.selection.height = p.selection.y1 - p.selection.y0;

  gimp_tile_cache_ntiles (2 * (p.selection.width / gimp_tile_width () + 1));

  /* TILES */
  division_x = p.params.division_x;
  division_y = p.params.division_y;
  if (p.params.fractional_type == FRACTIONAL_TYPE_FORCE)
    {
      if (0 < p.drawable->width  % p.params.tile_width) division_x++;
      if (0 < p.drawable->height % p.params.tile_height) division_y++;
      if (p.params.centering)
        {
          if (1 < p.drawable->width % p.params.tile_width)
            {
              division_x++;
              offset_x =
                (p.drawable->width % p.params.tile_width) / 2 -
                p.params.tile_width;
            }
          else
            {
              offset_x = 0;
            }

          if (1 < p.drawable->height % p.params.tile_height)
            {
              division_y++;
              offset_y =
                (p.drawable->height % p.params.tile_height) / 2 -
                p.params.tile_height;
            }
          else
            {
              offset_y = 0;
            }
        }
      else
        {
          offset_x = 0;
          offset_y = 0;
        }
    }
  else
    {
      if (p.params.centering)
        {
          offset_x = (p.drawable->width  % p.params.tile_width) / 2;
          offset_y = (p.drawable->height % p.params.tile_height) / 2;
        }
      else
        {
          offset_x = 0;
          offset_y = 0;
        }
    }

  move_max_pixels = p.params.move_max_rate * p.params.tile_width / 100.0;
  numof_tiles = division_x * division_y;
  t = tiles = g_new(Tile, numof_tiles);

  for (y = 0; y < division_y; y++)
    {
      gint srcy = offset_y + p.params.tile_height * y;

      for (x = 0; x < division_x; x++, t++)
        {
          gint srcx = offset_x + p.params.tile_width * x;

          if (srcx < 0)
            {
              t->x     = 0;
              t->width = srcx + p.params.tile_width;
            }
          else if (srcx + p.params.tile_width < p.drawable->width)
            {
              t->x     = srcx;
              t->width = p.params.tile_width;
            }
          else
            {
              t->x     = srcx;
              t->width = p.drawable->width - srcx;
            }

          if (srcy < 0)
            {
              t->y      = 0;
              t->height = srcy + p.params.tile_height;
            }
          else if (srcy + p.params.tile_height < p.drawable->height)
            {
              t->y      = srcy;
              t->height = p.params.tile_height;
            }
          else
            {
              t->y      = srcy;
              t->height = p.drawable->height - srcy;
            }

          t->z = g_rand_int (gr);
          random_move (&t->move_x, &t->move_y, move_max_pixels);
        }
    }

  qsort (tiles, numof_tiles, sizeof *tiles, tile_compare);

  gimp_pixel_rgn_get_rect (&src, pixels, 0, 0, p.drawable->width,
                           p.drawable->height);

  if (p.params.fractional_type == FRACTIONAL_TYPE_IGNORE)
    {
      clear_x0     = offset_x;
      clear_y0     = offset_y;
      clear_width  = p.params.tile_width * division_x;
      clear_height = p.params.tile_height * division_y;
    }
  else
    {
      clear_x0     = 0;
      clear_y0     = 0;
      clear_width  = p.drawable->width;
      clear_height = p.drawable->height;
    }

  clear_x1 = clear_x0 + clear_width;
  clear_y1 = clear_y0 + clear_height;

  switch (p.params.background_type)
    {
    case BACKGROUND_TYPE_TRANSPARENT:
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for (i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = 0;
                }
            }
        }
      break;

    case BACKGROUND_TYPE_INVERTED:
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              pixels[dindex+0] = 255 - pixels[dindex+0];
              pixels[dindex+1] = 255 - pixels[dindex+1];
              pixels[dindex+2] = 255 - pixels[dindex+2];
            }
        }
      break;

    case BACKGROUND_TYPE_IMAGE:
      break;

    case BACKGROUND_TYPE_FOREGROUND:
      gimp_context_get_foreground (&color);
      gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]);
      pixel[3] = 255;
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for (i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;

    case BACKGROUND_TYPE_BACKGROUND:
      gimp_context_get_background (&color);
      gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]);
      pixel[3] = 255;
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for(i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;

    case BACKGROUND_TYPE_COLOR:
      gimp_rgba_get_uchar (&p.params.background_color,
                           pixel, pixel + 1, pixel + 2, pixel + 3);
      for (y = clear_y0; y < clear_y1; y++)
        {
          for (x = clear_x0; x < clear_x1; x++)
            {
              dindex = p.drawable->bpp * (p.drawable->width * y + x);
              for(i = 0; i < p.drawable->bpp; i++)
                {
                  pixels[dindex+i] = pixel[i];
                }
            }
        }
      break;
    }

  /* DRAW */
  for (t = tiles, i = 0; i < numof_tiles; i++, t++)
    {
      gint x0 = t->x + t->move_x;
      gint y0 = t->y + t->move_y;

      gimp_pixel_rgn_get_rect (&src, buffer, t->x, t->y, t->width, t->height);

      for (y = 0; y < t->height; y++)
        {
          py = y0 + y;
          for (x = 0; x < t->width; x++)
            {
              px = x0 + x;
              sindex = p.drawable->bpp * (t->width * y + x);
              if (0 <= px && px < p.drawable->width &&
                  0 <= py && py < p.drawable->height)
                {
                  dindex = p.drawable->bpp * (p.drawable->width * py + px);
                  overlap(&pixels[dindex], &buffer[sindex]);
                }
              else if (p.params.wrap_around)
                {
                  px = (px + p.drawable->width)  % p.drawable->width;
                  py = (py + p.drawable->height) % p.drawable->height;
                  dindex = p.drawable->bpp * (p.drawable->width * py + px);
                  overlap(&pixels[dindex], &buffer[sindex]);
                }
            }
        }

      gimp_progress_update ((gdouble) i / (gdouble) numof_tiles);
    }

  gimp_pixel_rgn_set_rect (&dst, pixels, 0, 0, p.drawable->width,
                           p.drawable->height);

  gimp_progress_update (1.0);
  gimp_drawable_flush (p.drawable);
  gimp_drawable_merge_shadow (p.drawable->drawable_id, TRUE);
  gimp_drawable_update (p.drawable->drawable_id,
                        p.selection.x0, p.selection.y0,
                        p.selection.width, p.selection.height);

  g_rand_free (gr);
  g_free (buffer);
  g_free (pixels);
  g_free (tiles);
}
Esempio n. 16
0
gint32
load_image (const gchar  *filename,
            GimpRunMode   runmode,
            gboolean      preview,
            GError      **error)
{
  GimpPixelRgn     pixel_rgn;
  GimpDrawable    *drawable;
  gint32 volatile  image_ID;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  jpeg_saved_marker_ptr         marker;
  FILE            *infile;
  guchar          *buf;
  guchar         **rowbuf;
  gint             image_type;
  gint             layer_type;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
#ifdef HAVE_LIBEXIF
  gint             orientation = 0;
#endif
#ifdef HAVE_LCMS
  cmsHTRANSFORM    cmyk_transform = NULL;
#else
  gpointer         cmyk_transform = NULL;
#endif

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if (!preview)
    {
      jerr.pub.output_message = my_output_message;
    }

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  if (!preview)
    gimp_progress_init_printf (_("Opening '%s'"),
                               gimp_filename_to_utf8 (filename));

  image_ID = -1;

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
        fclose (infile);

      if (image_ID != -1 && !preview)
        gimp_image_delete (image_ID);

      if (preview)
        destroy_preview ();

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  if (! preview)
    {
      /* - step 2.1: tell the lib to save the comments */
      jpeg_save_markers (&cinfo, JPEG_COM, 0xffff);

      /* - step 2.2: tell the lib to save APP1 data (EXIF or XMP) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xffff);

      /* - step 2.3: tell the lib to save APP2 data (ICC profiles) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 2, 0xffff);
    }

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);
      return -1;
      break;
    }

  if (preview)
    {
      image_ID = preview_image_ID;
    }
  else
    {
      image_ID = gimp_image_new (cinfo.output_width, cinfo.output_height,
                                 image_type);

      gimp_image_undo_disable (image_ID);
      gimp_image_set_filename (image_ID, filename);
    }

  if (preview)
    {
      preview_layer_ID = gimp_layer_new (preview_image_ID, _("JPEG preview"),
                                         cinfo.output_width,
                                         cinfo.output_height,
                                         layer_type, 100, GIMP_NORMAL_MODE);
      layer_ID = preview_layer_ID;
    }
  else
    {
      layer_ID = gimp_layer_new (image_ID, _("Background"),
                                 cinfo.output_width,
                                 cinfo.output_height,
                                 layer_type, 100, GIMP_NORMAL_MODE);
    }

  drawable_global = drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
                       drawable->width, drawable->height, TRUE, FALSE);

  if (! preview)
    {
      GString  *comment_buffer = NULL;
      guint8   *profile        = NULL;
      guint     profile_size   = 0;
#ifdef HAVE_LIBEXIF
      ExifData *exif_data      = NULL;
#endif

      /* Step 5.0: save the original JPEG settings in a parasite */
      jpeg_detect_original_settings (&cinfo, image_ID);

      /* Step 5.1: check for comments, or EXIF metadata in APP1 markers */
      for (marker = cinfo.marker_list; marker; marker = marker->next)
        {
          const gchar *data = (const gchar *) marker->data;
          gsize        len  = marker->data_length;

          if (marker->marker == JPEG_COM)
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found image comment (%d bytes)\n",
                       marker->data_length);
#endif

              if (! comment_buffer)
                {
                  comment_buffer = g_string_new_len (data, len);
                }
              else
                {
                  /* concatenate multiple comments, separate them with LF */
                  g_string_append_c (comment_buffer, '\n');
                  g_string_append_len (comment_buffer, data, len);
                }
            }
          else if ((marker->marker == JPEG_APP0 + 1)
                   && (len > sizeof (JPEG_APP_HEADER_EXIF) + 8)
                   && ! strcmp (JPEG_APP_HEADER_EXIF, data))
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found EXIF block (%d bytes)\n",
                       (gint) (len - sizeof (JPEG_APP_HEADER_EXIF)));
#endif
#ifdef HAVE_LIBEXIF
              if (! exif_data)
                exif_data = exif_data_new ();
              /* if there are multiple blocks, their data will be merged */
              exif_data_load_data (exif_data, (unsigned char *) data, len);
#endif
            }
        }

#ifdef HAVE_LIBEXIF
      if (!jpeg_load_exif_resolution (image_ID, exif_data))
#endif
        jpeg_load_resolution (image_ID, &cinfo);

      /* if we found any comments, then make a parasite for them */
      if (comment_buffer && comment_buffer->len)
        {
          GimpParasite *parasite;

          jpeg_load_sanitize_comment (comment_buffer->str);
          parasite = gimp_parasite_new ("gimp-comment",
                                        GIMP_PARASITE_PERSISTENT,
                                        strlen (comment_buffer->str) + 1,
                                        comment_buffer->str);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);

          g_string_free (comment_buffer, TRUE);
        }

#ifdef HAVE_LIBEXIF
      /* if we found any EXIF block, then attach the metadata to the image */
      if (exif_data)
        {
          gimp_metadata_store_exif (image_ID, exif_data);
          orientation = jpeg_exif_get_orientation (exif_data);
          exif_data_unref (exif_data);
          exif_data = NULL;
        }
#endif

      /* Step 5.2: check for XMP metadata in APP1 markers (after EXIF) */
      for (marker = cinfo.marker_list; marker; marker = marker->next)
        {
          const gchar *data = (const gchar *) marker->data;
          gsize        len  = marker->data_length;

          if ((marker->marker == JPEG_APP0 + 1)
              && (len > sizeof (JPEG_APP_HEADER_XMP) + 20)
              && ! strcmp (JPEG_APP_HEADER_XMP, data))
            {
              GimpParam *return_vals;
              gint       nreturn_vals;
              gchar     *xmp_packet;

#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found XMP packet (%d bytes)\n",
                       (gint) (len - sizeof (JPEG_APP_HEADER_XMP)));
#endif
              xmp_packet = g_strndup (data + sizeof (JPEG_APP_HEADER_XMP),
                                      len - sizeof (JPEG_APP_HEADER_XMP));

              /* FIXME: running this through the PDB is not very efficient */
              return_vals = gimp_run_procedure ("plug-in-metadata-decode-xmp",
                                                &nreturn_vals,
                                                GIMP_PDB_IMAGE, image_ID,
                                                GIMP_PDB_STRING, xmp_packet,
                                                GIMP_PDB_END);

              if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS)
                {
                  g_warning ("JPEG - unable to decode XMP metadata packet");
                }

              gimp_destroy_params (return_vals, nreturn_vals);
              g_free (xmp_packet);
            }
        }

      /* Step 5.3: check for an embedded ICC profile in APP2 markers */
      jpeg_icc_read_profile (&cinfo, &profile, &profile_size);

      if (cinfo.out_color_space == JCS_CMYK)
        {
          cmyk_transform = jpeg_load_cmyk_transform (profile, profile_size);
        }
      else if (profile) /* don't attach the profile if we are transforming */
        {
          GimpParasite *parasite;

          parasite = gimp_parasite_new ("icc-profile",
                                        GIMP_PARASITE_PERSISTENT |
                                        GIMP_PARASITE_UNDOABLE,
                                        profile_size, profile);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);
        }

      g_free (profile);

      /* Do not attach the "jpeg-save-options" parasite to the image
       * because this conflicts with the global defaults (bug #75398).
       */
    }

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);

      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, drawable->width * scanlines,
                               cmyk_transform);

      gimp_pixel_rgn_set_rect (&pixel_rgn, buf,
                               0, start, drawable->width, scanlines);

      if (! preview && (cinfo.output_scanline % 32) == 0)
        gimp_progress_update ((gdouble) cinfo.output_scanline /
                              (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

#ifdef HAVE_LCMS
  if (cmyk_transform)
    cmsDeleteTransform (cmyk_transform);
#endif

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  /* Detach from the drawable and add it to the image.
   */
  if (! preview)
    {
      gimp_progress_update (1.0);
      gimp_drawable_detach (drawable);
    }

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);

#ifdef HAVE_LIBEXIF
  jpeg_exif_rotate_query (image_ID, orientation);
#endif

  return image_ID;
}
Esempio n. 17
0
static void
drawlens (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpImageType  drawtype = gimp_drawable_type (drawable->drawable_id);
  GimpPixelRgn   srcPR, destPR;
  gint           width, height;
  gint           bytes;
  gint           row;
  gint           x1, y1, x2, y2;
  guchar        *src, *dest;
  gint           i, col;
  gfloat         regionwidth, regionheight, dx, dy, xsqr, ysqr;
  gfloat         a, b, c, asqr, bsqr, csqr, x, y;
  glong          pixelpos, pos;
  GimpRGB        background;
  guchar         bgr_red, bgr_blue, bgr_green;
  guchar         alphaval;

  gimp_context_get_background (&background);
  gimp_rgb_get_uchar (&background,
                      &bgr_red, &bgr_green, &bgr_blue);

  bytes = drawable->bpp;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
      src = gimp_drawable_get_thumbnail_data (drawable->drawable_id,
                                              &width, &height, &bytes);
      regionwidth  = width;
      regionheight = height;
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
      regionwidth = x2 - x1;
      regionheight = y2 - y1;
      width = drawable->width;
      height = drawable->height;
      gimp_pixel_rgn_init (&srcPR, drawable,
                           0, 0, width, height, FALSE, FALSE);
      gimp_pixel_rgn_init (&destPR, drawable,
                           0, 0, width, height, TRUE, TRUE);

      src  = g_new (guchar, regionwidth * regionheight * bytes);
      gimp_pixel_rgn_get_rect (&srcPR, src,
                               x1, y1, regionwidth, regionheight);
    }

  dest = g_new (guchar, regionwidth * regionheight * bytes);

  a = regionwidth / 2;
  b = regionheight / 2;

  c = MIN (a, b);

  asqr = a * a;
  bsqr = b * b;
  csqr = c * c;

  for (col = 0; col < regionwidth; col++)
    {
      dx = (gfloat) col - a + 0.5;
      xsqr = dx * dx;
      for (row = 0; row < regionheight; row++)
        {
          pixelpos = (col + row * regionwidth) * bytes;
          dy = -((gfloat) row - b) - 0.5;
          ysqr = dy * dy;
          if (ysqr < (bsqr - (bsqr * xsqr) / asqr))
            {
              find_projected_pos (asqr, bsqr, csqr, dx, dy, &x, &y);
              y = -y;
              pos = ((gint) (y + b) * regionwidth + (gint) (x + a)) * bytes;

              for (i = 0; i < bytes; i++)
                {
                  dest[pixelpos + i] = src[pos + i];
                }
            }
          else
            {
              if (lvals.keep_surr)
                {
                  for (i = 0; i < bytes; i++)
                    {
                      dest[pixelpos + i] = src[pixelpos + i];
                    }
                }
              else
                {
                  if (lvals.set_transparent)
                    alphaval = 0;
                  else
                    alphaval = 255;

                  switch (drawtype)
                    {
                    case GIMP_INDEXEDA_IMAGE:
                      dest[pixelpos + 1] = alphaval;
                    case GIMP_INDEXED_IMAGE:
                      dest[pixelpos + 0] = 0;
                      break;

                    case GIMP_RGBA_IMAGE:
                      dest[pixelpos + 3] = alphaval;
                    case GIMP_RGB_IMAGE:
                      dest[pixelpos + 0] = bgr_red;
                      dest[pixelpos + 1] = bgr_green;
                      dest[pixelpos + 2] = bgr_blue;
                      break;

                    case GIMP_GRAYA_IMAGE:
                      dest[pixelpos + 1] = alphaval;
                    case GIMP_GRAY_IMAGE:
                      dest[pixelpos+0] = bgr_red;
                      break;
                    }
                }
            }
        }

      if (!preview)
        {
          if (((gint) (regionwidth-col) % 5) == 0)
            gimp_progress_update ((gdouble) col / (gdouble) regionwidth);
        }
    }

  if (preview)
    {
      gimp_preview_draw_buffer (preview, dest, bytes * regionwidth);
    }
  else
    {
      gimp_progress_update (1.0);
      gimp_pixel_rgn_set_rect (&destPR, dest, x1, y1,
                               regionwidth, regionheight);

      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1);
    }

  g_free (src);
  g_free (dest);
}
Esempio n. 18
0
// Run the plugin
static void
run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals)
{
	// Return values
  static GimpParam values[1];

  gint sel_x1, sel_y1, sel_x2, sel_y2, w, h, padding;
	PluginData         pd;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;

  *nreturn_vals = 1;
  *return_vals  = values;

  if (param[0].type!= GIMP_PDB_INT32) 
	  status=GIMP_PDB_CALLING_ERROR;
  if (param[2].type!=GIMP_PDB_DRAWABLE)
	  status=GIMP_PDB_CALLING_ERROR;

  run_mode = (GimpRunMode) param[0].data.d_int32;
	
	pd.drawable = gimp_drawable_get(param[2].data.d_drawable);
	gimp_drawable_mask_bounds(pd.drawable->drawable_id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
	pd.selection_width = sel_x2 - sel_x1;
  pd.selection_height = sel_y2 - sel_y1;
  pd.selection_offset_x = sel_x1;
  pd.selection_offset_y = sel_y1;
  pd.image_width = gimp_drawable_width(pd.drawable->drawable_id);
  pd.image_height = gimp_drawable_height(pd.drawable->drawable_id);
  pd.channel_count = gimp_drawable_bpp(pd.drawable->drawable_id);

  pd.point_grabbed = -1;

	if (run_mode == GIMP_RUN_INTERACTIVE)
	{
		// Interactive call with dialog
		dialog(&pd);
		if (pd.curve_user.count > 0)
		{
			gimp_set_data (PLUG_IN_BINARY, pd.curve_user.user_points, sizeof (GdkPoint) * pd.curve_user.count);
		}
	}
	else if (run_mode == GIMP_RUN_WITH_LAST_VALS)
	{
		// Read a saved curve and apply it
		fft_prepare(&pd);
		gimp_get_data(PLUG_IN_BINARY, pd.curve_user.user_points);
		pd.curve_user.count = gimp_get_data_size(PLUG_IN_BINARY) / sizeof (GdkPoint);
		gimp_pixel_rgn_init(&pd.region, pd.drawable, 0, 0, pd.image_width, pd.image_height, TRUE, TRUE);
		fft_apply(&pd);
		gimp_pixel_rgn_set_rect(&pd.region, pd.img_pixels, 0, 0, pd.image_width, pd.image_height);
		gimp_drawable_flush(pd.drawable);
		gimp_drawable_merge_shadow(pd.drawable->drawable_id, TRUE);
		gimp_drawable_update(pd.drawable->drawable_id, pd.selection_offset_x, pd.selection_offset_y, pd.selection_width, pd.selection_height);
		fft_destroy(&pd);
		gimp_displays_flush();
	}
	else
	{
	  status = GIMP_PDB_CALLING_ERROR;	
	}
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  gimp_drawable_detach(pd.drawable);
}
Esempio n. 19
0
// Create and handle the plugin's dialog
gboolean dialog(PluginData *pd)
{
	gimp_ui_init (PLUG_IN_BINARY, FALSE);
	GtkWidget *dialog, *main_hbox, *hbox_buttons, *preview, *graph, *vbox, *preview_button, *preview_hd_checkbox;
	dialog = gimp_dialog_new ("Frequency Curves", PLUG_IN_BINARY,
														NULL, (GtkDialogFlags)0,
														gimp_standard_help_func, PLUG_IN_NAME,
														GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
														GTK_STOCK_OK,     GTK_RESPONSE_OK,
														NULL);
	
	main_hbox = gtk_hbox_new (FALSE, 12);
	gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
	gtk_container_add (GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), main_hbox);
	
	curve_init(&pd->curve_user);
	curve_copy(&pd->curve_user, &pd->curve_fft);
	
	pd->preview = gimp_drawable_preview_new (pd->drawable, 0);
	gtk_box_pack_start (GTK_BOX (main_hbox), pd->preview, TRUE, TRUE, 0);
	gtk_widget_show (pd->preview);
	
	g_signal_connect_swapped (pd->preview, "invalidated", G_CALLBACK (preview_invalidated), pd);
	
	vbox = gtk_vbox_new (FALSE, 12);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
	gtk_container_add (GTK_CONTAINER(main_hbox), vbox);
	gtk_widget_show(vbox);
	
	graph = pd->graph = gtk_drawing_area_new();
	pd->graph_pixmap = NULL;
	gtk_widget_set_size_request (graph, GRAPH_WIDTH, GRAPH_HEIGHT);
	gtk_widget_set_events (graph, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | 
	                              GDK_POINTER_MOTION_HINT_MASK | GDK_ENTER_NOTIFY_MASK | 
	                              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 
	                              GDK_BUTTON1_MOTION_MASK);
	gtk_container_add (GTK_CONTAINER (vbox), graph);
	gtk_widget_show (graph);
	g_signal_connect (graph, "event", G_CALLBACK (graph_events), pd);
	
	hbox_buttons = gtk_hbox_new (FALSE, 12);
	gtk_container_set_border_width (GTK_CONTAINER (hbox_buttons), 12);
	gtk_container_add (GTK_CONTAINER(vbox), hbox_buttons);
	gtk_widget_show(hbox_buttons);
	
	preview_button = gtk_button_new_with_mnemonic ("HD _Preview");
	gtk_box_pack_start (GTK_BOX (hbox_buttons), preview_button, FALSE, FALSE, 0);
	gtk_widget_show (preview_button);
	g_signal_connect (preview_button, "clicked", G_CALLBACK (preview_hd), pd);
	
	preview_hd_checkbox = gtk_check_button_new_with_label("Always preview HD");
	gtk_box_pack_start (GTK_BOX (hbox_buttons), preview_hd_checkbox, FALSE, FALSE, 0);
	gtk_widget_show (preview_hd_checkbox);
	pd->do_preview_hd = FALSE;
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(preview_hd_checkbox), FALSE);
	g_signal_connect (preview_hd_checkbox, "toggled", G_CALLBACK (preview_hd_toggled), pd);
	
	gtk_widget_show(main_hbox);
	gtk_widget_show(dialog);
	fft_prepare(pd);
	histogram_generate(pd);
	wavelet_prepare(pd);
	gboolean run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
	if (run)
	{
		// set the region mode to actual writing
		gimp_pixel_rgn_init(&pd->region, pd->drawable, 0, 0, pd->image_width, pd->image_height, TRUE, TRUE);
		fft_apply(pd);
		gimp_pixel_rgn_set_rect(&pd->region, pd->img_pixels, 0, 0, pd->image_width, pd->image_height);
		// show the result
		gimp_drawable_flush(pd->drawable);
		gimp_drawable_merge_shadow(pd->drawable->drawable_id, TRUE);
		gimp_drawable_update(pd->drawable->drawable_id, pd->selection_offset_x, pd->selection_offset_y, pd->selection_width, pd->selection_height);
		gimp_displays_flush();
	}
	fft_destroy(pd);
	wavelet_destroy(pd);
	gtk_widget_destroy (dialog);
	return run;
}
Esempio n. 20
0
static gint32 load_image (char *filename)
{
	FILE *fp;

	gint32 image_ID = -1;
	gint32 layer_ID;
	GPixelRgn pixel_rgn;
	GDrawable *drawable;
	guchar *data;
	GDrawableType dtype;
	GImageType itype;
	struct stat st;
  
	int width, height, bpp=0;
	int i, j, k;
	int pelbytes, tileheight, wbytes, bsize, npels, pels, ncols, npals;
	int badread;
	gushort tmpval;

	if (stat (filename,&st) == -1) return -1;

	fp = fopen (filename, "rb");
	if (!fp) return -1;
	bs = (bs_header_t *) g_malloc (st.st_size);
	fread (bs,st.st_size,1,fp);
	fclose (fp);

	if (bs->magic != BS_MAGIC)
	{
		printf("not a .bs file\n");
		return -1;
	}

	gimp_get_data ("bs_width",&width);
	gimp_get_data ("bs_height",&height);

	printf("%d x %d\n",width,height);

	itype	= RGB;
	dtype	= RGB_IMAGE;

	image_ID = gimp_image_new (width, height, itype);
	gimp_image_set_filename (image_ID, filename);
	layer_ID = gimp_layer_new (image_ID,
		"Background",
		width, height,
		dtype,
		100,
		NORMAL_MODE);
	gimp_image_add_layer (image_ID, layer_ID, 0);
	drawable = gimp_drawable_get (layer_ID);
	gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, TRUE, FALSE);
	data = (guchar *) g_malloc (width * height * 3);

	bs_init();
	bs_decode_rgb24 (data,bs,width,height,0);
	
	printf ("image decoded!\n");
	
	gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, 0, width, height);
	g_free (data);
	gimp_drawable_flush (drawable);
	gimp_drawable_detach (drawable);
	return image_ID;
}
/*
 * Applies the algorithm
 */
static void
retinex (GimpDrawable *drawable,
         GimpPreview  *preview)
{
  gint          x, y, width, height;
  gint          size, bytes;
  guchar       *src  = NULL;
  guchar       *psrc = NULL;
  GimpPixelRgn  dst_rgn, src_rgn;

  bytes = drawable->bpp;

  /*
   * Get the size of the current image or its selection.
   */
  if (preview)
    {
      src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
                                          &width, &height, &bytes);
    }
  else
    {
      if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                          &x, &y, &width, &height))
        return;

      /* Allocate memory */
      size = width * height * bytes;
      src = g_try_malloc (sizeof (guchar) * size);

      if (src == NULL)
        {
          g_warning ("Failed to allocate memory");
          return;
        }

      memset (src, 0, sizeof (guchar) * size);

      /* Fill allocated memory with pixel data */
      gimp_pixel_rgn_init (&src_rgn, drawable,
                           x, y, width, height,
                           FALSE, FALSE);
      gimp_pixel_rgn_get_rect (&src_rgn, src, x, y, width, height);
    }

  /*
    Algorithm for Multi-scale Retinex with color Restoration (MSRCR).
   */
  psrc = src;
  MSRCR (psrc, width, height, bytes, preview != NULL);

  if (preview)
    {
      gimp_preview_draw_buffer (preview, psrc, width * bytes);
    }
  else
    {
      gimp_pixel_rgn_init (&dst_rgn, drawable,
                           x, y, width, height,
                           TRUE, TRUE);
      gimp_pixel_rgn_set_rect (&dst_rgn, psrc, x, y, width, height);

      gimp_progress_update (1.0);

      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x, y, width, height);
    }

  g_free (src);
}
Esempio n. 22
0
/* Decompose an image. It returns the number of new (gray) images.
   The image IDs for the new images are returned in image_ID_dst.
   On failure, -1 is returned.
*/
static gint32
decompose (gint32       image_ID,
           gint32       drawable_ID,
           const gchar *extract_type,
           gint32      *image_ID_dst,
           gint32      *nlayers,
           gint32      *layer_ID_dst)
{
  const gchar  *layername;
  gint          i, j, extract_idx, scan_lines;
  gint          height, width, tile_height, num_layers;
  gchar        *filename;
  guchar       *src;
  guchar       *dst[MAX_EXTRACT_IMAGES];
  GimpDrawable *drawable_src;
  GimpDrawable *drawable_dst[MAX_EXTRACT_IMAGES];
  GimpPixelRgn  pixel_rgn_src;
  GimpPixelRgn  pixel_rgn_dst[MAX_EXTRACT_IMAGES];

  extract_idx = -1;   /* Search extract type */
  for (j = 0; j < G_N_ELEMENTS (extract); j++)
    {
      if (g_ascii_strcasecmp (extract_type, extract[j].type) == 0)
	{
	  extract_idx = j;
	  break;
	}
    }
  if (extract_idx < 0)
    return -1;

  /* Check structure of source image */
  drawable_src = gimp_drawable_get (drawable_ID);
  if (drawable_src->bpp < 3)
    {
      g_message ("Not an RGB image.");
      return -1;
    }
  if ((extract[extract_idx].extract_fun == extract_alpha ||
       extract[extract_idx].extract_fun == extract_rgba) &&
      (!gimp_drawable_has_alpha (drawable_ID)))
    {
      g_message ("No alpha channel available.");
      return -1;
    }

  width  = drawable_src->width;
  height = drawable_src->height;

  tile_height = gimp_tile_height ();
  gimp_pixel_rgn_init (&pixel_rgn_src, drawable_src, 0, 0, width, height,
                       FALSE, FALSE);

  /* allocate a buffer for retrieving information from the src pixel region  */
  src = g_new (guchar, tile_height * width * drawable_src->bpp);

  /* Create all new gray images */
  num_layers = extract[extract_idx].num_images;
  if (num_layers > MAX_EXTRACT_IMAGES)
    num_layers = MAX_EXTRACT_IMAGES;

  for (j = 0; j < num_layers; j++)
    {
      /* Build a filename like <imagename>-<channel>.<extension> */
      gchar   *fname;
      gchar   *extension;
      gdouble  xres, yres;

      fname = gimp_image_get_filename (image_ID);

      if (fname)
        {
          extension = fname + strlen (fname) - 1;

          while (extension >= fname)
            {
              if (*extension == '.') break;
              extension--;
            }
          if (extension >= fname)
            {
              *(extension++) = '\0';

              if (decovals.as_layers)
                filename = g_strdup_printf ("%s-%s.%s", fname,
                                            gettext (extract[extract_idx].type),
                                            extension);
              else
                filename = g_strdup_printf ("%s-%s.%s", fname,
                                            gettext (extract[extract_idx].channel_name[j]),
                                            extension);
            }
          else
            {
              if (decovals.as_layers)
                filename = g_strdup_printf ("%s-%s", fname,
                                            gettext (extract[extract_idx].type));
              else
                filename = g_strdup_printf ("%s-%s", fname,
                                            gettext (extract[extract_idx].channel_name[j]));
            }
        }
      else
        {
          filename = g_strdup (gettext (extract[extract_idx].channel_name[j]));
        }

      gimp_image_get_resolution (image_ID, &xres, &yres);

      if (decovals.as_layers)
        {
          layername = gettext (extract[extract_idx].channel_name[j]);

          if (j == 0)
            image_ID_dst[j] = create_new_image (filename, layername,
                                                width, height, GIMP_GRAY,
                                                xres, yres,
                                                layer_ID_dst + j,
                                                drawable_dst + j,
                                                pixel_rgn_dst + j);
          else
            layer_ID_dst[j] = create_new_layer (image_ID_dst[0], j, layername,
                                                width, height, GIMP_GRAY,
                                                drawable_dst + j,
                                                pixel_rgn_dst + j);
        }
      else
        {
          image_ID_dst[j] = create_new_image (filename, NULL,
                                              width, height, GIMP_GRAY,
                                              xres, yres,
                                              layer_ID_dst + j,
                                              drawable_dst + j,
                                              pixel_rgn_dst + j);
        }

      g_free (filename);
      g_free (fname);
      dst[j] = g_new (guchar, tile_height * width);
    }

  i = 0;
  while (i < height)
    {
      /* Get source pixel region */
      scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
      gimp_pixel_rgn_get_rect (&pixel_rgn_src, src, 0, i, width, scan_lines);

      /* Extract the channel information */
      extract[extract_idx].extract_fun (src, drawable_src->bpp, scan_lines*width,
					dst);

      /* Transfer the registration color */
      if (decovals.use_registration)
        transfer_registration_color (src, drawable_src->bpp, scan_lines*width,
                                     dst, extract[extract_idx].num_images);

      /* Set destination pixel regions */
      for (j = 0; j < num_layers; j++)
	gimp_pixel_rgn_set_rect (&(pixel_rgn_dst[j]), dst[j], 0, i, width,
				 scan_lines);
      i += scan_lines;

      gimp_progress_update ((gdouble) i / (gdouble) height);
    }

  g_free (src);

  for (j = 0; j < num_layers; j++)
    {
      gimp_drawable_detach (drawable_dst[j]);
      gimp_drawable_update (layer_ID_dst[j], 0, 0,
                            gimp_drawable_width (layer_ID_dst[j]),
                            gimp_drawable_height (layer_ID_dst[j]));
      gimp_layer_add_alpha (layer_ID_dst[j]);
      g_free (dst[j]);
    }

  gimp_drawable_detach (drawable_src);

  *nlayers = num_layers;

  return (decovals.as_layers ? 1 : num_layers);
}
Esempio n. 23
0
static gboolean
pluginCore (piArgs *argp)
{
  GimpDrawable *drw, *ndrw = NULL;
  GimpPixelRgn  srcPr, dstPr;
  gboolean      success = TRUE;
  gint          nl      = 0;
  gint          y, i;
  gint          Y, I, Q;
  guint         width, height, bpp;
  gint          sel_x1, sel_x2, sel_y1, sel_y2;
  gint          prog_interval;
  guchar       *src, *s, *dst, *d;
  guchar        r, prev_r=0, new_r=0;
  guchar        g, prev_g=0, new_g=0;
  guchar        b, prev_b=0, new_b=0;
  gdouble       fy, fc, t, scale;
  gdouble       pr, pg, pb;
  gdouble       py;

  drw = gimp_drawable_get (argp->drawable);

  width  = drw->width;
  height = drw->height;
  bpp    = drw->bpp;

  if (argp->new_layerp)
    {
      gchar        name[40];
      const gchar *mode_names[] =
      {
        "ntsc",
        "pal",
      };
      const gchar *action_names[] =
      {
        "lum redux",
        "sat redux",
        "flag",
      };

      g_snprintf (name, sizeof (name), "hot mask (%s, %s)",
                  mode_names[argp->mode],
                  action_names[argp->action]);

      nl = gimp_layer_new (argp->image, name, width, height,
                           GIMP_RGBA_IMAGE, (gdouble)100, GIMP_NORMAL_MODE);
      ndrw = gimp_drawable_get (nl);
      gimp_drawable_fill (nl, GIMP_TRANSPARENT_FILL);
      gimp_image_insert_layer (argp->image, nl, -1, 0);
    }

  gimp_drawable_mask_bounds (drw->drawable_id,
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);

  width  = sel_x2 - sel_x1;
  height = sel_y2 - sel_y1;

  src = g_new (guchar, width * height * bpp);
  dst = g_new (guchar, width * height * 4);
  gimp_pixel_rgn_init (&srcPr, drw, sel_x1, sel_y1, width, height,
                       FALSE, FALSE);

  if (argp->new_layerp)
    {
      gimp_pixel_rgn_init (&dstPr, ndrw, sel_x1, sel_y1, width, height,
                           FALSE, FALSE);
    }
  else
    {
      gimp_pixel_rgn_init (&dstPr, drw, sel_x1, sel_y1, width, height,
                           TRUE, TRUE);
    }

  gimp_pixel_rgn_get_rect (&srcPr, src, sel_x1, sel_y1, width, height);

  s = src;
  d = dst;

  build_tab (argp->mode);

  gimp_progress_init (_("Hot"));
  prog_interval = height / 10;

  for (y = sel_y1; y < sel_y2; y++)
    {
      gint x;

      if (y % prog_interval == 0)
        gimp_progress_update ((double) y / (double) (sel_y2 - sel_y1));

      for (x = sel_x1; x < sel_x2; x++)
        {
          if (hotp (r = *(s + 0), g = *(s + 1), b = *(s + 2)))
            {
              if (argp->action == ACT_FLAG)
                {
                  for (i = 0; i < 3; i++)
                    *d++ = 0;
                  s += 3;
                  if (bpp == 4)
                    *d++ = *s++;
                  else if (argp->new_layerp)
                    *d++ = 255;
                }
              else
                {
                  /*
                   * Optimization: cache the last-computed hot pixel.
                   */
                  if (r == prev_r && g == prev_g && b == prev_b)
                    {
                      *d++ = new_r;
                      *d++ = new_g;
                      *d++ = new_b;
                      s += 3;
                      if (bpp == 4)
                        *d++ = *s++;
                      else if (argp->new_layerp)
                        *d++ = 255;
                    }
                  else
                    {
                      Y = tab[0][0][r] + tab[0][1][g] + tab[0][2][b];
                      I = tab[1][0][r] + tab[1][1][g] + tab[1][2][b];
                      Q = tab[2][0][r] + tab[2][1][g] + tab[2][2][b];

                      prev_r = r;
                      prev_g = g;
                      prev_b = b;
                      /*
                       * Get Y and chroma amplitudes in floating point.
                       *
                       * If your C library doesn't have hypot(), just use
                       * hypot(a,b) = sqrt(a*a, b*b);
                       *
                       * Then extract linear (un-gamma-corrected)
                       * floating-point pixel RGB values.
                       */
                      fy = (double)Y / (double)SCALE;
                      fc = hypot ((double) I / (double) SCALE,
                                  (double) Q / (double) SCALE);

                      pr = (double) pix_decode (r);
                      pg = (double) pix_decode (g);
                      pb = (double) pix_decode (b);

                      /*
                       * Reducing overall pixel intensity by scaling R,
                       * G, and B reduces Y, I, and Q by the same factor.
                       * This changes luminance but not saturation, since
                       * saturation is determined by the chroma/luminance
                       * ratio.
                       *
                       * On the other hand, by linearly interpolating
                       * between the original pixel value and a grey
                       * pixel with the same luminance (R=G=B=Y), we
                       * change saturation without affecting luminance.
                       */
                      if (argp->action == ACT_LREDUX)
                        {
                          /*
                           * Calculate a scale factor that will bring the pixel
                           * within both chroma and composite limits, if we scale
                           * luminance and chroma simultaneously.
                           *
                           * The calculated chrominance reduction applies
                           * to the gamma-corrected RGB values that are
                           * the input to the RGB-to-YIQ operation.
                           * Multiplying the original un-gamma-corrected
                           * pixel values by the scaling factor raised to
                           * the "gamma" power is equivalent, and avoids
                           * calling gc() and inv_gc() three times each.  */
                          scale = chroma_lim / fc;
                          t = compos_lim / (fy + fc);
                          if (t < scale)
                            scale = t;
                          scale = pow (scale, mode[argp->mode].gamma);

                          r = (guint8) pix_encode (scale * pr);
                          g = (guint8) pix_encode (scale * pg);
                          b = (guint8) pix_encode (scale * pb);
                        }
                      else
                        { /* ACT_SREDUX hopefully */
                          /*
                           * Calculate a scale factor that will bring the
                           * pixel within both chroma and composite
                           * limits, if we scale chroma while leaving
                           * luminance unchanged.
                           *
                           * We have to interpolate gamma-corrected RGB
                           * values, so we must convert from linear to
                           * gamma-corrected before interpolation and then
                           * back to linear afterwards.
                           */
                          scale = chroma_lim / fc;
                          t = (compos_lim - fy) / fc;
                          if (t < scale)
                            scale = t;

                          pr = gc (pr, argp->mode);
                          pg = gc (pg, argp->mode);
                          pb = gc (pb, argp->mode);

                          py = pr * mode[argp->mode].code[0][0] +
                               pg * mode[argp->mode].code[0][1] +
                               pb * mode[argp->mode].code[0][2];

                          r = pix_encode (inv_gc (py + scale * (pr - py),
                                                  argp->mode));
                          g = pix_encode (inv_gc (py + scale * (pg - py),
                                                  argp->mode));
                          b = pix_encode (inv_gc (py + scale * (pb - py),
                                                  argp->mode));
                        }

                      *d++ = new_r = r;
                      *d++ = new_g = g;
                      *d++ = new_b = b;

                      s += 3;

                      if (bpp == 4)
                        *d++ = *s++;
                      else if (argp->new_layerp)
                        *d++ = 255;
                    }
                }
            }
          else
            {
              if (!argp->new_layerp)
                {
                  for (i = 0; i < bpp; i++)
                    *d++ = *s++;
                }
              else
                {
                  s += bpp;
                  d += 4;
                }
            }
        }
    }

  gimp_pixel_rgn_set_rect (&dstPr, dst, sel_x1, sel_y1, width, height);

  g_free (src);
  g_free (dst);

  if (argp->new_layerp)
    {
      gimp_drawable_flush (ndrw);
      gimp_drawable_update (nl, sel_x1, sel_y1, width, height);
    }
  else
    {
      gimp_drawable_flush (drw);
      gimp_drawable_merge_shadow (drw->drawable_id, TRUE);
      gimp_drawable_update (drw->drawable_id, sel_x1, sel_y1, width, height);
    }

  gimp_displays_flush ();

  return success;
}
Esempio n. 24
0
static int
pr_ass_sub(PyGimpPixelRgn *self, PyObject *v, PyObject *w)
{
    GimpPixelRgn *pr = &(self->pr);
    PyObject *x, *y;
    const guchar *buf;
    Py_ssize_t len, x1, x2, xs, y1, y2, ys;

    if (w == NULL) {
        PyErr_SetString(PyExc_TypeError, "can't delete subscripts");
        return -1;
    }

    if (!PyString_Check(w)) {
        PyErr_SetString(PyExc_TypeError, "must assign string to subscript");
        return -1;
    }

    if (!PyTuple_Check(v) || PyTuple_Size(v) != 2) {
        PyErr_SetString(PyExc_TypeError, "subscript must be a 2-tuple");
        return -1;
    }

    if (!PyArg_ParseTuple(v, "OO", &x, &y))
        return -1;

    buf = (const guchar *)PyString_AsString(w);
    len = PyString_Size(w);
    if (!buf || len > INT_MAX) {
        return -1;
    }

    if (PyInt_Check(x)) {
        x1 = PyInt_AsSsize_t(x);
        if (x1 < pr->x || x1 >= pr->x + pr->w) {
            PyErr_SetString(PyExc_IndexError, "x subscript out of range");
            return -1;
        }

        if (PyInt_Check(y)) {
            y1 = PyInt_AsSsize_t(y);

            if (y1 < pr->y || y1 >= pr->y + pr->h) {
                PyErr_SetString(PyExc_IndexError, "y subscript out of range");
                return -1;
            }

            if (len != pr->bpp) {
                PyErr_SetString(PyExc_TypeError, "string is wrong length");
                return -1;
            }
            gimp_pixel_rgn_set_pixel(pr, buf, x1, y1);

        } else if (PySlice_Check(y)) {
            if (PySlice_GetIndices((PySliceObject *)y, pr->y + pr->h,
                                   &y1, &y2, &ys) ||
                y1 >= y2 || ys != 1) {
                PyErr_SetString(PyExc_IndexError, "invalid y slice");
                return -1;
            }
            if (y1 == 0)
                y1 = pr->y;

            if(y1 < pr->y || y2 < pr->y) {
                PyErr_SetString(PyExc_IndexError, "y subscript out of range");
                return -1;
            }
            if (len != pr->bpp * (y2 - y1)) {
                PyErr_SetString(PyExc_TypeError, "string is wrong length");
                return -1;
            }
            gimp_pixel_rgn_set_col(pr, buf, x1, y1, y2 - y1);

        } else {
            PyErr_SetString(PyExc_IndexError,"invalid y subscript");
            return -1;
        }
    } else if (PySlice_Check(x)) {
        if (PySlice_GetIndices((PySliceObject *)x, pr->x + pr->w,
                               &x1, &x2, &xs) ||
	        x1 >= x2 || xs != 1) {
            PyErr_SetString(PyExc_IndexError, "invalid x slice");
	        return -1;
        }
        if(x1 == 0)
            x1 = pr->x;

        if(x1 < pr->x || x2 < pr->x) {
            PyErr_SetString(PyExc_IndexError, "x subscript out of range");
            return -1;
        }

        if (PyInt_Check(y)) {
            y1 = PyInt_AsSsize_t(y);

            if (y1 < pr->y || y1 >= pr->y + pr->h) {
                PyErr_SetString(PyExc_IndexError, "y subscript out of range");
                return -1;
            }

            if (len != pr->bpp * (x2 - x1)) {
                PyErr_SetString(PyExc_TypeError, "string is wrong length");
                return -1;
            }
            gimp_pixel_rgn_set_row(pr, buf, x1, y1, x2 - x1);

        } else if (PySlice_Check(y)) {
            if (PySlice_GetIndices((PySliceObject *)y, pr->y + pr->h,
                                   &y1, &y2, &ys) ||
                y1 >= y2 || ys != 1) {
                PyErr_SetString(PyExc_IndexError, "invalid y slice");
                return -1;
            }
            if (y1 == 0)
                y1 = pr->y;

            if(y1 < pr->y || y2 < pr->y) {
                PyErr_SetString(PyExc_IndexError, "y subscript out of range");
                return -1;
            }
            if (len != pr->bpp * (x2 - x1) * (y2 - y1)) {
                PyErr_SetString(PyExc_TypeError, "string is wrong length");
                return -1;
            }
            gimp_pixel_rgn_set_rect(pr, buf, x1, y1, x2 - x1, y2 - y1);

        } else {
            PyErr_SetString(PyExc_IndexError,"invalid y subscript");
            return -1;
        }
    } else {
        PyErr_SetString(PyExc_TypeError, "invalid x subscript");
        return -1;
    }
    return 0;
}
Esempio n. 25
0
void ptRun(const gchar*     Name,
           gint       NrParameters,
           const GimpParam* Parameter,
           gint *nreturn_vals,
           GimpParam **return_vals) {
  printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  printf("Name         : '%s'\n",Name);
  printf("NrParameters : %d\n",NrParameters);
  if (!strcmp(Name,"photivoSendToGimp")) {
    printf("RunMode      : %d\n",Parameter[0].data.d_int32);
    printf("FileName1    : '%s'\n",Parameter[1].data.d_string);
    printf("FileName2    : '%s'\n",Parameter[2].data.d_string);

    QFile GimpFile(Parameter[1].data.d_string);
    bool result = GimpFile.open(QIODevice::ReadOnly | QIODevice::Text);
    assert(result);

    QTextStream In(&GimpFile);

    QString ImageFileName = In.readLine();
    QString ExifFileName  = In.readLine();
    QString ICCFileName   = In.readLine();

    // Read image
    FILE *InputFile = fopen(ImageFileName.toLocal8Bit().data(),"rb");
    if (!InputFile) {
      ptLogError(1,ImageFileName.toLocal8Bit().data());
      return; // ptError_FileOpen;
    }

    short    Colors;
    unsigned short Width;
    unsigned short Height;
    unsigned short BitsPerColor;
    char     Buffer[128];

    // Extremely naive. Probably just enough for testcases.
    char *s = fgets(Buffer,127,InputFile);
    assert ( s );
    int n = sscanf(Buffer,"P%hd",&Colors);
    assert ( 1 == n );
    assert(Colors == 6 );
    do {
      s = fgets(Buffer,127,InputFile);
      assert ( s );
    } while (Buffer[0] == '#');
    sscanf(Buffer,"%hd %hd",&Width,&Height);
    s = fgets(Buffer,127,InputFile);
    assert ( s );
    sscanf(Buffer,"%hd",&BitsPerColor);
    assert(BitsPerColor == 0xffff);

    Colors = 3;

    unsigned short (* ImageForGimp)[3] =
      (unsigned short (*)[3]) CALLOC2(Width*Height,sizeof(*ImageForGimp));
    ptMemoryError(ImageForGimp,__FILE__,__LINE__);

    unsigned short*  PpmRow = (unsigned short *) CALLOC2(Width*Height,sizeof(*PpmRow));
    ptMemoryError(PpmRow,__FILE__,__LINE__);

    for (unsigned short Row=0; Row<Height; Row++) {
      size_t RV = fread(PpmRow,Colors*2,Width,InputFile);
      if (RV != (size_t) Width) {
        printf("ReadPpm error. Expected %d bytes. Got %d\n",Width,(int)RV);
        exit(EXIT_FAILURE);
      }
      if (htons(0x55aa) != 0x55aa) {
        swab((char *)PpmRow,(char *)PpmRow,Width*Colors*2);
      }
      for (unsigned short Col=0; Col<Width; Col++) {
        for (short c=0;c<3;c++) {
          ImageForGimp[Row*Width+Col][c] = PpmRow[Col*Colors+c];
        }
      }
    }

    FREE2(PpmRow);
    FCLOSE(InputFile);

    QFile ExifFile(ExifFileName);
    result = ExifFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize = ExifFile.size();
    QDataStream ExifIn(&ExifFile);
    char* ExifBuffer = (char *) MALLOC2(FileSize);
    ptMemoryError(ExifBuffer,__FILE__,__LINE__);
    unsigned ExifBufferLength = ExifIn.readRawData(ExifBuffer,FileSize);
    ExifFile.close();

    QFile ICCFile(ICCFileName);
    result = ICCFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize2 = ICCFile.size();
    QDataStream ICCIn(&ICCFile);
    char* ICCBuffer = (char *) MALLOC2(FileSize2);
    ptMemoryError(ICCBuffer,__FILE__,__LINE__);
    unsigned ICCBufferLength = ICCIn.readRawData(ICCBuffer,FileSize2);
    ICCFile.close();

    // And now copy to gimp.
    gint32 GimpImage = gimp_image_new(Width,
                                      Height,
                                      GIMP_RGB);
    assert (GimpImage != -1);
    gint32 GimpLayer = gimp_layer_new(GimpImage,
                                      "BG",
                                      Width,
                                      Height,
                                      GIMP_RGB_IMAGE,
                                      100.0,
                                      GIMP_NORMAL_MODE);
#if GIMP_MINOR_VERSION<=6
    gimp_image_add_layer(GimpImage,GimpLayer,0);
#else
    gimp_image_insert_layer(GimpImage,GimpLayer,0,0);
#endif
    GimpDrawable* Drawable = gimp_drawable_get(GimpLayer);
    GimpPixelRgn PixelRegion;
    gimp_pixel_rgn_init(&PixelRegion,
                        Drawable,
                        0,
                        0,
                        Drawable->width,
                        Drawable->height,
                        true,
                        false);
    unsigned short TileHeight = gimp_tile_height();
    for (unsigned short Row=0; Row<Height; Row+=TileHeight) {
      unsigned short NrRows = MIN(Height-Row, (int)TileHeight);
      guint8* Buffer = g_new(guint8,TileHeight*Width*3);
      for (unsigned short i=0; i<NrRows; i++) {
        for (unsigned short j=0; j<Width; j++) {
          for (short c=0;c<3;c++) {
            Buffer[3*(i*Width+j)+c] =
              ImageForGimp[(Row+i)*Width+j][c]>>8;
          }
        }
      }
      gimp_pixel_rgn_set_rect(&PixelRegion,
                              Buffer,
                              0,
                              Row,
                              Width,
                              NrRows);
      g_free(Buffer);
    }
    gimp_drawable_flush(Drawable);
    gimp_drawable_detach(Drawable);
    FREE2(ImageForGimp);
    GimpParasite* GimpExifData = gimp_parasite_new("exif-data",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ExifBufferLength,
                                                   ExifBuffer);
    gimp_image_parasite_attach(GimpImage,GimpExifData);
    gimp_parasite_free(GimpExifData);
    FREE2(ExifBuffer);

    GimpParasite* GimpICCData = gimp_parasite_new("icc-profile",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ICCBufferLength,
                                                   ICCBuffer);
    gimp_image_parasite_attach(GimpImage,GimpICCData);
    gimp_parasite_free(GimpICCData);
    FREE2(ICCBuffer);

    static GimpParam Values[2];
    *nreturn_vals = 2;
    *return_vals = Values;
    Values[0].type = GIMP_PDB_STATUS;
    Values[0].data.d_status = GIMP_PDB_SUCCESS;
    Values[1].type = GIMP_PDB_IMAGE;
    Values[1].data.d_image = GimpImage;

    QFile::remove(ImageFileName);
    QFile::remove(ExifFileName);
    QFile::remove(ICCFileName);
    QFile::remove(Parameter[1].data.d_string);

  }
Esempio n. 26
0
static gint32
ReadImage (FILE        *fd,
           const gchar *filename,
           gint         len,
           gint         height,
           CMap         cmap,
           gint         ncols,
           gint         format,
           gint         interlace,
           gint         number,
           guint        leftpos,
           guint        toppos,
           guint        screenwidth,
           guint        screenheight)
{
  static gint32 image_ID   = -1;
  static gint   frame_number = 1;

  gint32        layer_ID;
  GimpPixelRgn  pixel_rgn;
  GimpDrawable *drawable;
  guchar       *dest, *temp;
  guchar        c;
  gint          xpos = 0, ypos = 0, pass = 0;
  gint          cur_progress, max_progress;
  gint          v;
  gint          i, j;
  gchar        *framename;
  gchar        *framename_ptr;
  gboolean      alpha_frame = FALSE;
  static gint   previous_disposal;

  /* Guard against bogus frame size */
  if (len < 1 || height < 1)
    {
      g_message ("Bogus frame dimensions");
      return -1;
    }

  /*
   **  Initialize the Compression routines
   */
  if (! ReadOK (fd, &c, 1))
    {
      g_message ("EOF / read error on image data");
      return -1;
    }

  if (LZWReadByte (fd, TRUE, c) < 0)
    {
      g_message ("Error while reading");
      return -1;
    }

  if (frame_number == 1)
    {
      /* Guard against bogus logical screen size values */
      if (screenwidth == 0)
        screenwidth = len;

      if (screenheight == 0)
        screenheight = height;

      image_ID = gimp_image_new (screenwidth, screenheight, GIMP_INDEXED);
      gimp_image_set_filename (image_ID, filename);

      for (i = 0, j = 0; i < ncols; i++)
        {
          used_cmap[0][i] = gimp_cmap[j++] = cmap[0][i];
          used_cmap[1][i] = gimp_cmap[j++] = cmap[1][i];
          used_cmap[2][i] = gimp_cmap[j++] = cmap[2][i];
        }

      gimp_image_set_colormap (image_ID, gimp_cmap, ncols);

      if (Gif89.delayTime < 0)
        framename = g_strdup (_("Background"));
      else
        framename = g_strdup_printf (_("Background (%d%s)"),
                                     10 * Gif89.delayTime, "ms");

      previous_disposal = Gif89.disposal;

      if (Gif89.transparent == -1)
        {
          layer_ID = gimp_layer_new (image_ID, framename,
                                     len, height,
                                     GIMP_INDEXED_IMAGE, 100, GIMP_NORMAL_MODE);
        }
      else
        {
          layer_ID = gimp_layer_new (image_ID, framename,
                                     len, height,
                                     GIMP_INDEXEDA_IMAGE, 100, GIMP_NORMAL_MODE);
          alpha_frame=TRUE;
        }

      g_free (framename);
    }
  else /* NOT FIRST FRAME */
    {
      gimp_progress_set_text_printf (_("Opening '%s' (frame %d)"),
                                     gimp_filename_to_utf8 (filename),
                                     frame_number);
      gimp_progress_pulse ();

       /* If the colourmap is now different, we have to promote to RGB! */
      if (! promote_to_rgb)
        {
          for (i = 0; i < ncols; i++)
            {
              if ((used_cmap[0][i] != cmap[0][i]) ||
                  (used_cmap[1][i] != cmap[1][i]) ||
                  (used_cmap[2][i] != cmap[2][i]))
                {
                  /* Everything is RGB(A) from now on... sigh. */
                  promote_to_rgb = TRUE;

                  /* Promote everything we have so far into RGB(A) */
#ifdef GIFDEBUG
                  g_print ("GIF: Promoting image to RGB...\n");
#endif
                  gimp_image_convert_rgb (image_ID);

                  break;
                }
            }
        }

      if (Gif89.delayTime < 0)
        framename = g_strdup_printf (_("Frame %d"), frame_number);
      else
        framename = g_strdup_printf (_("Frame %d (%d%s)"),
                                     frame_number, 10 * Gif89.delayTime, "ms");

      switch (previous_disposal)
        {
        case 0x00:
          break; /* 'don't care' */
        case 0x01:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (combine)", NULL);
          g_free (framename_ptr);
          break;
        case 0x02:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (replace)", NULL);
          g_free (framename_ptr);
          break;
        case 0x03:  /* Rarely-used, and unhandled by many
                       loaders/players (including GIMP: we treat as
                       'combine' mode). */
          framename_ptr = framename;
          framename = g_strconcat (framename, " (combine) (!)", NULL);
          g_free (framename_ptr);
          break;
        case 0x04: /* I've seen a composite of this type. stvo_online_banner2.gif */
        case 0x05:
        case 0x06: /* I've seen a composite of this type. bn31.Gif */
        case 0x07:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (unknown disposal)", NULL);
          g_free (framename_ptr);
          g_message (_("GIF: Undocumented GIF composite type %d is "
                       "not handled.  Animation might not play or "
                       "re-save perfectly."),
                     previous_disposal);
          break;
        default:
          g_message ("Disposal word got corrupted.  Bug.");
          break;
        }
      previous_disposal = Gif89.disposal;

      layer_ID = gimp_layer_new (image_ID, framename,
                                 len, height,
                                 promote_to_rgb ?
                                 GIMP_RGBA_IMAGE : GIMP_INDEXEDA_IMAGE,
                                 100, GIMP_NORMAL_MODE);
      alpha_frame = TRUE;
      g_free (framename);
    }

  frame_number++;

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);
  gimp_layer_translate (layer_ID, (gint) leftpos, (gint) toppos);

  drawable = gimp_drawable_get (layer_ID);

  cur_progress = 0;
  max_progress = height;

  if (alpha_frame)
    dest = (guchar *) g_malloc (len * height * (promote_to_rgb ? 4 : 2));
  else
    dest = (guchar *) g_malloc (len * height);

#ifdef GIFDEBUG
    g_print ("GIF: reading %d by %d%s GIF image, ncols=%d\n",
             len, height, interlace ? " interlaced" : "", ncols);
#endif

  if (! alpha_frame && promote_to_rgb)
    {
      /* I don't see how one would easily construct a GIF in which
         this could happen, but it's a mad mad world. */
      g_message ("Ouch!  Can't handle non-alpha RGB frames.\n"
                 "Please file a bug report in GIMP's bugzilla.");
      gimp_quit ();
    }

  while ((v = LZWReadByte (fd, FALSE, c)) >= 0)
    {
      if (alpha_frame)
        {
          if (((guchar) v > highest_used_index) && !(v == Gif89.transparent))
            highest_used_index = (guchar) v;

          if (promote_to_rgb)
            {
              temp = dest + ( (ypos * len) + xpos ) * 4;
              *(temp  ) = (guchar) cmap[0][v];
              *(temp+1) = (guchar) cmap[1][v];
              *(temp+2) = (guchar) cmap[2][v];
              *(temp+3) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
            }
          else
            {
              temp = dest + ( (ypos * len) + xpos ) * 2;
              *temp = (guchar) v;
              *(temp+1) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
            }
        }
      else
        {
          if ((guchar) v > highest_used_index)
            highest_used_index = (guchar) v;

          temp = dest + (ypos * len) + xpos;
          *temp = (guchar) v;
        }

      xpos++;
      if (xpos == len)
        {
          xpos = 0;
          if (interlace)
            {
              switch (pass)
                {
                case 0:
                case 1:
                  ypos += 8;
                  break;
                case 2:
                  ypos += 4;
                  break;
                case 3:
                  ypos += 2;
                  break;
                }

              if (ypos >= height)
                {
                  pass++;
                  switch (pass)
                    {
                    case 1:
                      ypos = 4;
                      break;
                    case 2:
                      ypos = 2;
                      break;
                    case 3:
                      ypos = 1;
                      break;
                    default:
                      goto fini;
                    }
                }
            }
          else
            {
              ypos++;
            }

          if (frame_number == 1)
            {
              cur_progress++;
              if ((cur_progress % 16) == 0)
                gimp_progress_update ((gdouble) cur_progress /
                                      (gdouble) max_progress);
            }
        }

      if (ypos >= height)
        break;
    }

 fini:
  if (LZWReadByte (fd, FALSE, c) >= 0)
    g_print ("GIF: too much input data, ignoring extra...\n");

  gimp_pixel_rgn_init (&pixel_rgn, drawable,
                       0, 0, drawable->width, drawable->height, TRUE, FALSE);
  gimp_pixel_rgn_set_rect (&pixel_rgn, dest,
                           0, 0, drawable->width, drawable->height);

  g_free (dest);

  gimp_drawable_flush (drawable);
  gimp_drawable_detach (drawable);

  return image_ID;
}
Esempio n. 27
0
gint32
load_thumbnail_image (const gchar  *filename,
                      gint         *width,
                      gint         *height,
                      GError      **error)
{
  gint32 volatile  image_ID;
  ExifData        *exif_data;
  GimpPixelRgn     pixel_rgn;
  GimpDrawable    *drawable;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  guchar          *buf;
  guchar         **rowbuf;
  gint             image_type;
  gint             layer_type;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
  gint             orientation;
  my_src_ptr       src;
  FILE            *infile;

  image_ID = -1;
  exif_data = jpeg_exif_data_new_from_file (filename, NULL);

  if (! ((exif_data) && (exif_data->data) && (exif_data->size > 0)))
    return -1;

  orientation = jpeg_exif_get_orientation (exif_data);

  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit     = my_error_exit;
  jerr.pub.output_message = my_output_message;

  gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                             gimp_filename_to_utf8 (filename));

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.  We
       * need to clean up the JPEG object, close the input file,
       * and return.
       */
      jpeg_destroy_decompress (&cinfo);

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  if (cinfo.src == NULL)
    cinfo.src = (struct jpeg_source_mgr *)(*cinfo.mem->alloc_small)
      ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
       sizeof (my_source_mgr));

  src = (my_src_ptr) cinfo.src;

  src->pub.init_source       = init_source;
  src->pub.fill_input_buffer = fill_input_buffer;
  src->pub.skip_input_data   = skip_input_data;
  src->pub.resync_to_restart = jpeg_resync_to_restart;
  src->pub.term_source       = term_source;

  src->pub.bytes_in_buffer   = exif_data->size;
  src->pub.next_input_byte   = exif_data->data;

  src->buffer = exif_data->data;
  src->size = exif_data->size;

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before
   * reading the data.  After jpeg_start_decompress() we have the
   * correct scaled output image dimensions available, as well as
   * the output colormap if we asked for color quantization.  In
   * this example, we need to make an output work buffer of the
   * right size.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  /* Create a new image of the proper size and associate the
   * filename with it.
   */
  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
      break;
    }

  image_ID = gimp_image_new (cinfo.output_width, cinfo.output_height,
                             image_type);

  gimp_image_undo_disable (image_ID);
  gimp_image_set_filename (image_ID, filename);

  jpeg_load_resolution (image_ID, &cinfo);

  layer_ID = gimp_layer_new (image_ID, _("Background"),
                             cinfo.output_width,
                             cinfo.output_height,
                             layer_type, 100, GIMP_NORMAL_MODE);

  drawable_global = drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
                       drawable->width, drawable->height, TRUE, FALSE);

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);
      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, drawable->width * scanlines, NULL);

      gimp_pixel_rgn_set_rect (&pixel_rgn, buf,
                               0, start, drawable->width, scanlines);

      gimp_progress_update ((gdouble) cinfo.output_scanline /
                            (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal
   * of memory.
   */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* At this point you may want to check to see whether any
   * corrupt-data warnings occurred (test whether
   * jerr.num_warnings is nonzero).
   */
  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);


  /* NOW to get the dimensions of the actual image to return the
   * calling app
   */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  jerr.pub.output_message = my_output_message;

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.  We
       * need to clean up the JPEG object, close the input file,
       * and return.
       */
      jpeg_destroy_decompress (&cinfo);

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  jpeg_start_decompress (&cinfo);

  *width  = cinfo.output_width;
  *height = cinfo.output_height;

  /* Step 4: Release JPEG decompression object */

  /* This is an important step since it will release a good deal
   * of memory.
   */
  jpeg_destroy_decompress (&cinfo);

  fclose (infile);

  if (exif_data)
    {
      exif_data_unref (exif_data);
      exif_data = NULL;
    }

  jpeg_exif_rotate (image_ID, orientation);

  return image_ID;
}
Esempio n. 28
0
static void run ( const gchar *name, gint nparams, const GimpParam *param,
                  gint *nreturn_vals, GimpParam **return_vals)
{
  static GimpParam values[3];
  GimpRunMode run_mode;
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  SeparateContext mysc;
  //enum separate_function func = SEP_NONE;
  run_mode = param[0].data.d_int32;


  /* setup for localization */
  INIT_I18N ();

  cmsErrorAction( LCMS_ERROR_IGNORE );

  mysc.filename = NULL;
  if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) )
    status = GIMP_PDB_CALLING_ERROR;
  else if( run_mode == GIMP_RUN_NONINTERACTIVE ) {
    if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 )
      status = GIMP_PDB_CALLING_ERROR;
    else
      mysc.filename = g_strdup( param[1].data.d_string );
  } else {
    gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" );
    if( size ) {
      mysc.filename = g_malloc( size );
      gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename );
    }
  }

  if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) {
    gint i, j, x, y;
    TIFF *in;
    guint32 width, height, stripSize, stripCount, stripHeight;
    gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit;
    float xres, yres;
    const gchar *layerNames[] = { "C", "M", "Y", "K" };
    guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile;
    gint32 layers[5], masks[4];
    GimpDrawable *drw[4];
    GimpPixelRgn rgn[4];
    GimpRGB primaries[4] = { { .180, .541, .870, 1.0 },
                             { .925, .149, .388, 1.0 },
                             { .929, .862, .129, 1.0 },
                             { 0, 0, 0, 1.0 }  };

    gchar *str = NULL;
    gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) );

#ifdef G_OS_WIN32
    {
      gchar *_filename = NULL; // win32 filename encoding(not UTF-8)
      _filename = g_win32_locale_filename_from_utf8( mysc.filename );
      in = TIFFOpen( _filename ? _filename : mysc.filename, "r" );
      g_free( _filename );
    }
#else
    in = TIFFOpen( mysc.filename, "r" );
#endif

    if( !in ) {
      str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName );
      gimp_message( str );
      g_free( str );
      status = GIMP_PDB_EXECUTION_ERROR;
    } else {
      if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) ||
          ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) ||
          ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) ||
          ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) ||
          ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) {
        str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName );
        gimp_message( str );
        g_free( str );
        status = GIMP_PDB_EXECUTION_ERROR;
      } else {
        stripCount = TIFFNumberOfStrips( in );
        stripSize = TIFFStripSize( in );
        TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width );
        TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height );
        TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight );
        TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit );
        TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres );
        TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres );

#if 0
        str = g_strdup_printf( "Photometric : %d  BPS : %d  SPP : %d\nInkset : %d  StripCount : %d", photometric, bps, spp, inkset, stripCount );
        gimp_message( str );
        g_free( str );
#endif

        step = ( bps == 16 ) ? 2 : 1;

        buf = g_malloc( stripSize );

        values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB );
        gimp_image_set_resolution( values[1].data.d_image, xres, yres );
        gimp_context_push();
        for( i = 0; i < 4; i++ ) {
          layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE );
          gimp_context_set_foreground( &primaries[i] );
          gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL );
          gimp_image_add_layer( values[1].data.d_image, layers[i], i );
          masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK );
          gimp_layer_add_mask( layers[i], masks[i] );
          drw[i] = gimp_drawable_get( masks[i] );
          maskbuf[i] = g_malloc( width * stripHeight );
        }
        gimp_context_pop();
        layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE );
        gimp_drawable_fill( layers[4], GIMP_WHITE_FILL );
        gimp_image_add_layer( values[1].data.d_image, layers[4], 4 );

        str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName );
        gimp_progress_init( str );
        g_free( str );

        for( i = 0; i < stripCount; i++ ) {
          guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize );
          guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight );
          srcbuf = buf;
          if( bps == 16 )
            srcbuf++;
          for( j = 0; j < 4; j++ ) {
            gimp_pixel_rgn_init( &( rgn[j] ), drw[j],
                                 0, stripHeight * i, width, rowCount,
                                 FALSE, FALSE );
            destbuf[j] = maskbuf[j];
          }
          for( y = 0; y < rowCount; y++ ) {
            for( x = 0; x < width; x++ ) {
              *destbuf[0]++ = *srcbuf;
              srcbuf += step;
              *destbuf[1]++ = *srcbuf;
              srcbuf += step;
              *destbuf[2]++ = *srcbuf;
              srcbuf += step;
              *destbuf[3]++ = *srcbuf;
              srcbuf += step;
              //srcbuf += spp > 4 ? spp - 4 : 0;
            }
          }
          gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount );
          gimp_progress_update( (gdouble)i / stripCount );
        }
        g_free( buf );
        for( i = 0; i < 4; i++ ) {
          g_free( maskbuf[i] );
          gimp_drawable_detach( drw[i] );
        }

#ifdef ENABLE_COLOR_MANAGEMENT
        if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) {
          GimpParasite *parasite;

          parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile );
          gimp_image_parasite_attach( values[1].data.d_image, parasite );
          gimp_parasite_free( parasite );

          //g_free( iccProfile ); // This causes clash on TIFFClose( in ).
        }
#endif
      }
      TIFFClose( in );
    }
    g_free( baseName );
  } else
    status = GIMP_PDB_CANCEL;

  *return_vals = values;
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  if( status == GIMP_PDB_SUCCESS ) {
    *nreturn_vals = 2;
    values[1].type = GIMP_PDB_IMAGE;
    if( run_mode != GIMP_RUN_NONINTERACTIVE ) {
      gimp_image_undo_enable( values[1].data.d_image );
      gimp_display_new( values[1].data.d_image );
      gimp_displays_flush();
    }
    gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 );
  } else
    *nreturn_vals = 1;

  g_free( mysc.filename );
}
Esempio n. 29
0
static void
ico_dialog_update_icon_preview (GtkWidget *dialog,
                                gint32     layer,
                                gint       bpp)
{
  GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer);
  GdkPixbuf *pixbuf;
  gint       w       = gimp_drawable_width (layer);
  gint       h       = gimp_drawable_height (layer);

  if (! preview)
    return;

  if (bpp <= 8)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      guchar       *cmap;
      gint          num_colors;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      gimp_image_convert_indexed (tmp_image,
                                  GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                  1 <<bpp, TRUE, FALSE, "dummy");

      cmap = gimp_image_get_colormap (tmp_image, &num_colors);
      if ( num_colors == (1 << bpp) &&
           !ico_cmap_contains_black (cmap, num_colors))
        {
          /* Windows icons with color maps need the color black.
           * We need to eliminate one more color to make room for black.
           */
          if (gimp_drawable_is_indexed (layer))
            {
              g_free (cmap);
              cmap = gimp_image_get_colormap (image, &num_colors);
              gimp_image_set_colormap (tmp_image, cmap, num_colors);
            }
          else if (gimp_drawable_is_gray (layer))
            {
              gimp_image_convert_grayscale (tmp_image);
            }
          else
            {
              gimp_image_convert_rgb (tmp_image);
            }

          tmp = gimp_drawable_get (tmp_layer);
          gimp_pixel_rgn_init (&dst_pixel_rgn,
                               tmp, 0, 0, w, h, TRUE, FALSE);
          gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
          gimp_drawable_detach (tmp);

          if (!gimp_drawable_is_rgb (layer))
            gimp_image_convert_rgb (tmp_image);

          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      (1<<bpp) - 1, TRUE, FALSE, "dummy");
        }
      g_free (cmap);
      g_free (buffer);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else if (bpp == 24)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      GimpParam    *return_vals;
      gint          n_return_vals;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
      g_free (buffer);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      return_vals =
        gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                            GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_IMAGE, tmp_image,
                            GIMP_PDB_DRAWABLE, tmp_layer,
                            GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                            GIMP_PDB_END);
      gimp_destroy_params (return_vals, n_return_vals);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else
    {
      pixbuf = gimp_drawable_get_thumbnail (layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);
    }

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  g_object_unref (pixbuf);
}
Esempio n. 30
0
/* Create a layer with the provided image data and add it to the image */
gboolean create_layer(gint32   image_ID,
                      uint8_t *layer_data,
                      gint32   position,
                      gchar   *name,
                      gint     width,
                      gint     height,
                      gint32   offsetx,
                      gint32   offsety)
{
    gint32        layer_ID;
#ifdef GIMP_2_9
    GeglBuffer   *geglbuffer;
    GeglRectangle extent;
#else
    GimpDrawable *drawable;
    GimpPixelRgn  region;
#endif

    layer_ID = gimp_layer_new(image_ID,
                              name,
                              width, height,
	                          GIMP_RGBA_IMAGE,
	                          100,
                              GIMP_NORMAL_MODE);

#ifdef GIMP_2_9
	/* Retrieve the buffer for the layer */
	geglbuffer = gimp_drawable_get_buffer(layer_ID);

	/* Copy the image data to the region */
    gegl_rectangle_set(&extent, 0, 0, width, height);
    gegl_buffer_set(geglbuffer, &extent, 0, NULL, layer_data, GEGL_AUTO_ROWSTRIDE);

	/* Flush the drawable and detach */
    gegl_buffer_flush(geglbuffer);

	g_object_unref(geglbuffer);
#else
    /* Retrieve the drawable for the layer */
    drawable = gimp_drawable_get(layer_ID);

    /* Get a pixel region from the layer */
    gimp_pixel_rgn_init(&region,
                        drawable,
                        0, 0,
                        width, height,
                        FALSE, FALSE);

    /* Copy the image data to the region */
    gimp_pixel_rgn_set_rect(&region,
                            layer_data,
                            0, 0,
                            width, height);

    /* Flush the drawable and detach */
    gimp_drawable_flush(drawable);
    gimp_drawable_detach(drawable);
#endif

    /* Add the new layer to the image */
    gimp_image_insert_layer(image_ID, layer_ID, -1, position);

    /* If layer offsets were provided, use them to position the image */
    if (offsetx || offsety) {
        gimp_layer_set_offsets(layer_ID, offsetx, offsety);
    }

    /* TODO: fix this */
    return TRUE;
}