Esempio n. 1
0
static int test_rpng(const char *in_path)
{
#ifdef HAVE_IMLIB2
   Imlib_Image img;
   const uint32_t *imlib_data = NULL;
#endif
   const uint32_t test_data[] = {
      0xff000000 | 0x50, 0xff000000 | 0x80,
      0xff000000 | 0x40, 0xff000000 | 0x88,
      0xff000000 | 0x50, 0xff000000 | 0x80,
      0xff000000 | 0x40, 0xff000000 | 0x88,
      0xff000000 | 0xc3, 0xff000000 | 0xd3,
      0xff000000 | 0xc3, 0xff000000 | 0xd3,
      0xff000000 | 0xc3, 0xff000000 | 0xd3,
      0xff000000 | 0xc3, 0xff000000 | 0xd3,
   };
   uint32_t *data = NULL;
   unsigned width = 0;
   unsigned height = 0;

   if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16))
      return 1;

   if (!rpng_load_image_argb(in_path, &data, &width, &height))
      return 2;

   fprintf(stderr, "Path: %s.\n", in_path);
   fprintf(stderr, "Got image: %u x %u.\n", width, height);

#if 0
   fprintf(stderr, "\nRPNG:\n");
   for (unsigned h = 0; h < height; h++)
   {
      unsigned w;
      for (w = 0; w < width; w++)
         fprintf(stderr, "[%08x] ", data[h * width + w]);
      fprintf(stderr, "\n");
   }
#endif

#ifdef HAVE_IMLIB2
   /* Validate with imlib2 as well. */
   img = imlib_load_image(in_path);
   if (!img)
      return 4;

   imlib_context_set_image(img);

   width      = imlib_image_get_width();
   height     = imlib_image_get_width();
   imlib_data = imlib_image_get_data_for_reading_only();

#if 0
   fprintf(stderr, "\nImlib:\n");
   for (unsigned h = 0; h < height; h++)
   {
      for (unsigned w = 0; w < width; w++)
         fprintf(stderr, "[%08x] ", imlib_data[h * width + w]);
      fprintf(stderr, "\n");
   }
#endif

   if (memcmp(imlib_data, data, width * height * sizeof(uint32_t)) != 0)
   {
      fprintf(stderr, "Imlib and RPNG differs!\n");
      return 5;
   }
   else
      fprintf(stderr, "Imlib and RPNG are equivalent!\n");

   imlib_free_image();
#endif
   free(data);

   return 0;
}
Esempio n. 2
0
File: image.c Progetto: pts/pts-qiv
/*
 *    Load & display image
 */
void qiv_load_image(qiv_image *q) {
  /* Don't initialize most variables here, initialize them after load_next_image: */
  struct stat st;
  const char *image_name;
  Imlib_Image *im;
  struct timeval load_before, load_after;

  char is_stat_ok;
  /* Used to omit slow disk operations if image_file doesn't exist or isn't
   * a file.
   */
  char is_maybe_image_file;
  char is_first_error = 1;

 load_next_image:
  is_stat_ok = 0;
  is_maybe_image_file = 1;
  image_name = image_names[image_idx];
  gettimeofday(&load_before, 0);

  if (imlib_context_get_image())
    imlib_free_image();

  q->real_w = q->real_h = -2;
  q->has_thumbnail = FALSE;
  if (!do_omit_load_stat) {
    is_stat_ok = 0 == stat(image_name, &st);
    is_maybe_image_file = is_stat_ok && S_ISREG(st.st_mode);
  }
  current_mtime = is_stat_ok ? st.st_mtime : 0;
  im = NULL;
  if (thumbnail && fullscreen && (is_stat_ok || maxpect)) {
    char *th_image_name =
        is_maybe_image_file ?
        get_thumbnail_filename(image_name, &is_maybe_image_file) : NULL;
    if (th_image_name) {
      im = imlib_load_image(th_image_name);
      if (im && maxpect) {
        get_image_dimensions(image_name, th_image_name,
                             &q->real_w, &q->real_h);
      }
      free(th_image_name);
      th_image_name = NULL;
    }
  }
  if (im) {  /* We have a dumb thumbnail in im. */
    if (maxpect) {
      current_mtime = 0;
      q->has_thumbnail = TRUE;
      /* Now im still has the thumbnail image. Keep it. */
    } else {  /* Use the real, non-thumbnail image instead. */
      imlib_context_set_image(im);
      imlib_free_image();
      im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL;
    }
  } else {
    im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL;
  }

  if (!im) { /* error */
    q->error = 1;
    q->orig_w = 400;
    q->orig_h = 300;

    if (to_root || to_root_t || to_root_s) {
      fprintf(stderr, "qiv: cannot load background_image\n");
      qiv_exit(1);
    }

    /* Shortcut to speed up lots of subsequent load failures. */
    if (is_first_error) {
      check_size(q, TRUE);
      if (first) {
        setup_win(q);
        first = 0;
      }
      gdk_window_set_background(q->win, &error_bg);
      gdk_beep();
      is_first_error = 0;
    }

    /* TODO(pts): Avoid the slow loop of copying pointers around in update_image_on_error. */
    update_image_on_error(q);
    /* This is a shortcut to avoid stack overflow in the recursion of
     * qiv_load_image -> update_image -> qiv_load_image -> update_image -> ...
     * if there are errors loading many subsequent images.
     */
    goto load_next_image;
  }

  if (thumbnail && !q->has_thumbnail && q->real_w < 0 && is_maybe_image_file) {
    FILE *f = fopen(image_name, "rb");
    if (f) {
      get_real_dimensions_fast(f, &q->real_w, &q->real_h);
      fclose(f);
    }
  }

  /* Retrieve image properties */
  imlib_context_set_image(im);
  q->error = 0;
  q->orig_w = imlib_image_get_width();
  q->orig_h = imlib_image_get_height();
  if (q->orig_w >= (1 << 23) / q->orig_h) {
    /* Workaround for Imlib2 1.4.6 on Ubuntu Trusty: PNG images with an
     * alpha channel and pixel count >= (1 << 23) are displayed as black.
     * imlib_image_query_pixel returns the correct value, but
     * imlib_render_pixmaps_for_whole_image_at_size renders only black
     * pixels if unzoomed.
     */
    Imlib_Color c;
    /* Without this call, imlib_image_set_has_alpha(0) is too early, and
     * it has no effect.
     */
    imlib_image_query_pixel(0, 0, &c);
    imlib_image_set_has_alpha(0);
  }
#ifdef HAVE_EXIF
  if (autorotate) {
    transform( q, orient( image_name));
  }
#endif

  check_size(q, TRUE);

  if (first) {
    setup_win(q);
    first = 0;
  }

  /* desktop-background -> exit */
  if (to_root || to_root_t || to_root_s) {
    set_desktop_image(q);
    if(slide)
      return;
    else
      qiv_exit(0);
  }

  gdk_window_set_background(q->win, &image_bg);

  if (do_grab || (fullscreen && !disable_grab) ) {
    gdk_keyboard_grab(q->win, FALSE, CurrentTime);
    gdk_pointer_grab(q->win, FALSE,
      GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK |
      GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, CurrentTime);
  }

  gettimeofday(&load_after, 0);
  /* load_elapsed used by update_image. */
  load_elapsed = ((load_after.tv_sec +  load_after.tv_usec / 1.0e6) -
                 (load_before.tv_sec + load_before.tv_usec / 1.0e6));

  update_image(q, FULL_REDRAW);
//    if (magnify && !fullscreen) {  // [lc]
//     setup_magnify(q, &magnify_img);
//     update_magnify(q, &magnify_img, FULL_REDRAW, 0, 0);
//    }
}
Esempio n. 3
0
static int
x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h)
{
    struct x11_info *xi;
#if defined(USE_IMLIB)
    ImlibImage *im;
#elif defined(USE_IMLIB2)
    Imlib_Image im;
#elif defined(USE_GDKPIXBUF)
    GdkPixbufAnimation *animation;
    GList *frames;
    int i, j, iw, ih, n, frame_num, delay, max_anim;
    double ratio_w, ratio_h;
    struct x11_image *ximg;
    Pixmap tmp_pixmap;
#endif

    if (self == NULL)
	return 0;
    xi = (struct x11_info *)self->priv;
    if (xi == NULL)
	return 0;

#if defined(USE_IMLIB)
    im = Imlib_load_image(xi->id, fname);
    if (!im)
	return 0;
    if (w <= 0)
	w = im->rgb_width;
    if (h <= 0)
	h = im->rgb_height;
    img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h,
					DefaultDepth(xi->display, 0));
    if (!img->pixmap)
	return 0;
    XSetForeground(xi->display, xi->imageGC, xi->background_pixel);
    XFillRectangle(xi->display, (Pixmap) img->pixmap, xi->imageGC, 0, 0, w, h);
    Imlib_paste_image(xi->id, im, (Pixmap) img->pixmap, 0, 0, w, h);
    Imlib_kill_image(xi->id, im);
#elif defined(USE_IMLIB2)
    im = imlib_load_image(fname);
    if (!im)
	return 0;
    imlib_context_set_image(im);
    if (w <= 0)
	w = imlib_image_get_width();
    if (h <= 0)
	h = imlib_image_get_height();
    img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h,
					DefaultDepth(xi->display, 0));
    if (!img->pixmap)
	return 0;
    XSetForeground(xi->display, xi->imageGC, xi->background_pixel);
    XFillRectangle(xi->display, (Pixmap) img->pixmap, xi->imageGC, 0, 0, w, h);
    imlib_context_set_display(xi->display);
    imlib_context_set_visual(DefaultVisual(xi->display, 0));
    imlib_context_set_colormap(DefaultColormap(xi->display, 0));
    imlib_context_set_drawable((Drawable) img->pixmap);
    imlib_render_image_on_drawable_at_size(0, 0, w, h);
    imlib_free_image();
#elif defined(USE_GDKPIXBUF)
    max_anim = self->max_anim;
    animation = gdk_pixbuf_animation_new_from_file(fname);
    if (!animation)
	return 0;
    frames = gdk_pixbuf_animation_get_frames(animation);
    frame_num = n = gdk_pixbuf_animation_get_num_frames(animation);

    get_animation_size(animation, &iw, &ih, &delay);
    if (delay <= 0)
	max_anim = -1;

    if (max_anim < 0) {
	frame_num = (-max_anim > n) ? n : -max_anim;
    }
    else if (max_anim > 0) {
	frame_num = n = (max_anim > n) ? n : max_anim;
    }

    if (w < 1 || h < 1) {
	w = iw;
	h = ih;
	ratio_w = ratio_h = 1;
    }
    else {
	ratio_w = 1.0 * w / iw;
	ratio_h = 1.0 * h / ih;
    }
    tmp_pixmap = XCreatePixmap(xi->display, xi->parent, w, h,
			       DefaultDepth(xi->display, 0));
    XFillRectangle(xi->display, (Pixmap) tmp_pixmap, xi->imageGC, 0, 0, w, h);
    if (!tmp_pixmap) {
	gdk_pixbuf_animation_unref(animation);
	return 0;
    }
    ximg = x11_img_new(xi, w, h, frame_num);
    if (!ximg) {
	XFreePixmap(xi->display, tmp_pixmap);
	gdk_pixbuf_animation_unref(animation);
	return 0;
    }
    for (j = 0; j < n; j++) {
	GdkPixbufFrame *frame;
	GdkPixbuf *org_pixbuf, *pixbuf;
	int width, height, ofstx, ofsty;

	if (max_anim < 0) {
	    i = (j - n + frame_num > 0) ? (j - n + frame_num) : 0;
	}
	else {
	    i = j;
	}
	frame = (GdkPixbufFrame *) g_list_nth_data(frames, j);
	org_pixbuf = gdk_pixbuf_frame_get_pixbuf(frame);
	ofstx = gdk_pixbuf_frame_get_x_offset(frame);
	ofsty = gdk_pixbuf_frame_get_y_offset(frame);
	delay = gdk_pixbuf_frame_get_delay_time(frame);
	width = gdk_pixbuf_get_width(org_pixbuf);
	height = gdk_pixbuf_get_height(org_pixbuf);

	if (ofstx == 0 && ofsty == 0 && width == w && height == h) {
	    pixbuf = resize_image(org_pixbuf, w, h);
	}
	else {
	    pixbuf =
		resize_image(org_pixbuf, width * ratio_w, height * ratio_h);
	    ofstx *= ratio_w;
	    ofsty *= ratio_h;
	}
	width = gdk_pixbuf_get_width(pixbuf);
	height = gdk_pixbuf_get_height(pixbuf);

	if (delay > ximg->delay)
	    ximg->delay = delay;

	XCopyArea(xi->display, tmp_pixmap, ximg->pixmap[i],
		  xi->imageGC, 0, 0, w, h, 0, 0);
	gdk_pixbuf_xlib_render_to_drawable_alpha(pixbuf,
						 (Drawable) ximg->pixmap[i], 0,
						 0, ofstx, ofsty, width,
						 height,
						 GDK_PIXBUF_ALPHA_BILEVEL, 1,
						 XLIB_RGB_DITHER_NORMAL, 0, 0);

	switch (gdk_pixbuf_frame_get_action(frame)) {
	case GDK_PIXBUF_FRAME_RETAIN:
	    XCopyArea(xi->display, ximg->pixmap[i], tmp_pixmap,
		      xi->imageGC, 0, 0, w, h, 0, 0);
	    break;
	case GDK_PIXBUF_FRAME_DISPOSE:
	    break;
	case GDK_PIXBUF_FRAME_REVERT:
	    XCopyArea(xi->display, ximg->pixmap[0], tmp_pixmap,
		      xi->imageGC, 0, 0, w, h, 0, 0);
	    break;
	default:
	    XCopyArea(xi->display, ximg->pixmap[0], tmp_pixmap,
		      xi->imageGC, 0, 0, w, h, 0, 0);
	    break;
	}


	if (org_pixbuf != pixbuf)
	    gdk_pixbuf_finalize(pixbuf);

    }
    XFreePixmap(xi->display, tmp_pixmap);
    gdk_pixbuf_animation_unref(animation);
    img->pixmap = ximg;
#endif

    img->width = w;
    img->height = h;
    return 1;
}