Esempio n. 1
0
cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf) {
    int chan = gdk_pixbuf_get_n_channels(gdkbuf);
    if (chan < 3) return NULL;

#if GDK_PIXBUF_CHECK_VERSION(2,32,0)
    const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf);
#else
    const guint8* gdkpix = gdk_pixbuf_get_pixels(gdkbuf);
#endif
    if (!gdkpix) {
        return NULL;
    }
    gint w = gdk_pixbuf_get_width(gdkbuf);
    gint h = gdk_pixbuf_get_height(gdkbuf);
    int stride = gdk_pixbuf_get_rowstride(gdkbuf);

    cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
    cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h);
    cairo_surface_flush (cs);
    if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
        return NULL;
    }

    int cstride = cairo_image_surface_get_stride(cs);
    unsigned char * cpix = cairo_image_surface_get_data(cs);

    if (chan == 3) {
        int i;
        for (i = h; i; --i) {
            const guint8 *gp = gdkpix;
            unsigned char *cp = cpix;
            const guint8* end = gp + 3*w;
            while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
                cp[0] = gp[2];
                cp[1] = gp[1];
                cp[2] = gp[0];
#else
                cp[1] = gp[0];
                cp[2] = gp[1];
                cp[3] = gp[2];
#endif
                gp += 3;
                cp += 4;
            }
            gdkpix += stride;
            cpix += cstride;
        }
    } else {
        /* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255
         * (z/255) = z/256 * 256/255     = z/256 (1 + 1/255)
         *         = z/256 + (z/256)/255 = (z + z/255)/256
         *         # recurse once
         *         = (z + (z + z/255)/256)/256
         *         = (z + z/256 + z/256/255) / 256
         *         # only use 16bit uint operations, loose some precision,
         *         # result is floored.
         *       ->  (z + z>>8)>>8
         *         # add 0x80/255 = 0.5 to convert floor to round
         *       =>  (z+0x80 + (z+0x80)>>8 ) >> 8
         * ------
         * tested as equal to lround(z/255.0) for uint z in [0..0xfe02]
         */
#define PREMUL_ALPHA(x,a,b,z) G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } G_STMT_END
        int i;
        for (i = h; i; --i) {
            const guint8 *gp = gdkpix;
            unsigned char *cp = cpix;
            const guint8* end = gp + 4*w;
            guint z1, z2, z3;
            while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
                PREMUL_ALPHA(cp[0], gp[2], gp[3], z1);
                PREMUL_ALPHA(cp[1], gp[1], gp[3], z2);
                PREMUL_ALPHA(cp[2], gp[0], gp[3], z3);
                cp[3] = gp[3];
#else
                PREMUL_ALPHA(cp[1], gp[0], gp[3], z1);
                PREMUL_ALPHA(cp[2], gp[1], gp[3], z2);
                PREMUL_ALPHA(cp[3], gp[2], gp[3], z3);
                cp[0] = gp[3];
#endif
                gp += 4;
                cp += 4;
            }
            gdkpix += stride;
            cpix += cstride;
        }
#undef PREMUL_ALPHA
    }
    cairo_surface_mark_dirty(cs);
    return cs;
}
Esempio n. 2
0
void  image_adjust_levels(GdkPixbuf *img)
{
    guchar *pixels = gdk_pixbuf_get_pixels(img);
    int width = gdk_pixbuf_get_width(img);
    int height = gdk_pixbuf_get_height(img);
    int rowstride = gdk_pixbuf_get_rowstride(img);
    guchar *row, *pixel;
    int x, y;
    guchar r,g,b;
    guchar min, max;
    gint scale, bias;

    g_assert(gdk_pixbuf_get_n_channels(img) == 4);

    /* First pass through the image, take min/max */
    min = 0xFF;
    max = 0x00;
    row = pixels;
    for (y=0; y<height; y++) {
        pixel = row;
        for (x=0; x<width; x++) {

            r = *(pixel++);
            min = MIN(min, r);
            max = MAX(max, r);

            g = *(pixel++);
            min = MIN(min, g);
            max = MAX(max, g);

            b = *(pixel++);
            min = MIN(min, b);
            max = MAX(max, b);

            pixel++;
        }
        row += rowstride;
    }

    /* Calculate a scale (in fixed point) and bias */
    if (max <= min)
        return;
    bias = -min;
    scale = (255 << 16) / (max - min);

    /* Second pass, applying the scale and bias */
    row = pixels;
    for (y=0; y<height; y++) {
        pixel = row;
        for (x=0; x<width; x++) {

            *pixel = (((*pixel) + bias) * scale) >> 16;
            pixel++;
            *pixel = (((*pixel) + bias) * scale) >> 16;
            pixel++;
            *pixel = (((*pixel) + bias) * scale) >> 16;
            pixel++;
            pixel++;
        }
        row += rowstride;
    }

}
Esempio n. 3
0
void
output_pixbuf (FILE *outfile, gboolean ext_symbols,
               const char *varname,
               GdkPixbuf *pixbuf)
{
  const char *modifier;
  const guchar *p;
  const guchar *end;
  gboolean has_alpha;
  int column;
  
  modifier = "static ";
  if (ext_symbols)
    modifier = "";
  
  g_fprintf (outfile, "%sconst guchar ", modifier);
  fputs (varname, outfile);
  fputs ("[] =\n", outfile);
  fputs ("{\n", outfile);

  p = gdk_pixbuf_get_pixels (pixbuf);
  end = p + gdk_pixbuf_get_rowstride (pixbuf) * gdk_pixbuf_get_height (pixbuf);
  has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);

  /* Sync the order of writing with the order of reading in
   * gdk-pixbuf-data.c
   */
  output_int (outfile, GDK_PIXBUF_INLINE_MAGIC_NUMBER, "File magic");
  output_int (outfile, GDK_PIXBUF_INLINE_RAW, "Format of following stuff");
  output_int (outfile, gdk_pixbuf_get_rowstride (pixbuf), "Rowstride");
  output_int (outfile, gdk_pixbuf_get_width (pixbuf), "Width");
  output_int (outfile, gdk_pixbuf_get_height (pixbuf), "Height");

  output_bool (outfile, has_alpha, "Has an alpha channel");

  output_int (outfile, gdk_pixbuf_get_colorspace (pixbuf), "Colorspace (0 == RGB, no other options implemented)");

  output_int (outfile, gdk_pixbuf_get_n_channels (pixbuf), "Number of channels");

  output_int (outfile, gdk_pixbuf_get_bits_per_sample (pixbuf), "Bits per sample");

  fputs ("  /* Image data */\n", outfile);
  
  /* Copy the data in the pixbuf */
  column = 0;
  while (p != end)
    {
      guchar r, g, b, a;
      
      r = *p;
      ++p;
      g = *p;
      ++p;
      b = *p;
      ++p;
      if (has_alpha)
        {
          a = *p;
          ++p;
        }
      else
        a = 0;

      
      if (has_alpha)
        g_fprintf (outfile, "  0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x", r, g, b, a);
      else
        g_fprintf (outfile, "  0x%.2x, 0x%.2x, 0x%.2x", r, g, b);

      if (p != end)
        fputs (",", outfile);
      else
        fputs ("\n", outfile);
      
      ++column;
      
      if (column > 2)
        {
          fputs ("\n", outfile);
          column = 0;
        }
    }

  fputs ("};\n\n", outfile);
}
Esempio n. 4
0
/**
 * Computes and returns the average color of a {@link Gdk.Pixbuf}.
 * The resulting color is the average of all pixels which aren't
 * nearly transparent while saturated pixels are weighted more than
 * "grey" ones.
 *
 * @param source the pixbuf to use
 * @return the average color of the pixbuf
 */
void plank_drawing_drawing_service_average_color (GdkPixbuf* source, PlankDrawingColor* result) {
	guint8 r = 0U;
	guint8 g = 0U;
	guint8 b = 0U;
	guint8 a = 0U;
	guint8 min = 0U;
	guint8 max = 0U;
	gdouble delta = 0.0;
	gdouble rTotal = 0.0;
	gdouble gTotal = 0.0;
	gdouble bTotal = 0.0;
	gdouble bTotal2 = 0.0;
	gdouble gTotal2 = 0.0;
	gdouble rTotal2 = 0.0;
	gdouble aTotal2 = 0.0;
	guint8* dataPtr = NULL;
	GdkPixbuf* _tmp0_ = NULL;
	guint8* _tmp1_ = NULL;
	gint n_channels = 0;
	GdkPixbuf* _tmp2_ = NULL;
	gint _tmp3_ = 0;
	gint _tmp4_ = 0;
	gint width = 0;
	GdkPixbuf* _tmp5_ = NULL;
	gint _tmp6_ = 0;
	gint _tmp7_ = 0;
	gint height = 0;
	GdkPixbuf* _tmp8_ = NULL;
	gint _tmp9_ = 0;
	gint _tmp10_ = 0;
	gint rowstride = 0;
	GdkPixbuf* _tmp11_ = NULL;
	gint _tmp12_ = 0;
	gint _tmp13_ = 0;
	gint length = 0;
	gint _tmp14_ = 0;
	gint _tmp15_ = 0;
	gint pixels = 0;
	gint _tmp16_ = 0;
	gint _tmp17_ = 0;
	gint _tmp18_ = 0;
	gdouble scoreTotal = 0.0;
	gint _tmp75_ = 0;
	gdouble _tmp77_ = 0.0;
	gint _tmp78_ = 0;
	gdouble _tmp79_ = 0.0;
	gint _tmp80_ = 0;
	gdouble _tmp81_ = 0.0;
	gint _tmp82_ = 0;
	gdouble _tmp83_ = 0.0;
	gint _tmp84_ = 0;
	gdouble _tmp85_ = 0.0;
	gdouble _tmp92_ = 0.0;
	gint _tmp93_ = 0;
	guint8 _tmp94_ = 0U;
	gdouble _tmp95_ = 0.0;
	gint _tmp96_ = 0;
	guint8 _tmp97_ = 0U;
	gdouble _tmp98_ = 0.0;
	gint _tmp99_ = 0;
	guint8 _tmp100_ = 0U;
	gdouble _tmp101_ = 0.0;
	gint _tmp102_ = 0;
	guint8 _tmp103_ = 0U;
	gdouble _tmp104_ = 0.0;
	gdouble max_val = 0.0;
	gdouble _tmp119_ = 0.0;
	gdouble _tmp120_ = 0.0;
	gdouble _tmp121_ = 0.0;
	gdouble _tmp122_ = 0.0;
	gdouble _tmp123_ = 0.0;
	gdouble _tmp124_ = 0.0;
	gdouble _tmp131_ = 0.0;
	gdouble _tmp132_ = 0.0;
	gdouble _tmp133_ = 0.0;
	gdouble _tmp134_ = 0.0;
	PlankDrawingColor _tmp135_ = {0};
	g_return_if_fail (source != NULL);
	rTotal = 0.0;
	gTotal = 0.0;
	bTotal = 0.0;
	bTotal2 = 0.0;
	gTotal2 = 0.0;
	rTotal2 = 0.0;
	aTotal2 = 0.0;
	_tmp0_ = source;
	_tmp1_ = gdk_pixbuf_get_pixels (_tmp0_);
	dataPtr = _tmp1_;
	_tmp2_ = source;
	_tmp3_ = gdk_pixbuf_get_n_channels (_tmp2_);
	_tmp4_ = _tmp3_;
	n_channels = _tmp4_;
	_tmp5_ = source;
	_tmp6_ = gdk_pixbuf_get_width (_tmp5_);
	_tmp7_ = _tmp6_;
	width = _tmp7_;
	_tmp8_ = source;
	_tmp9_ = gdk_pixbuf_get_height (_tmp8_);
	_tmp10_ = _tmp9_;
	height = _tmp10_;
	_tmp11_ = source;
	_tmp12_ = gdk_pixbuf_get_rowstride (_tmp11_);
	_tmp13_ = _tmp12_;
	rowstride = _tmp13_;
	_tmp14_ = width;
	_tmp15_ = height;
	length = _tmp14_ * _tmp15_;
	_tmp16_ = height;
	_tmp17_ = rowstride;
	_tmp18_ = n_channels;
	pixels = (_tmp16_ * _tmp17_) / _tmp18_;
	scoreTotal = 0.0;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp19_ = FALSE;
			_tmp19_ = TRUE;
			while (TRUE) {
				gint _tmp21_ = 0;
				gint _tmp22_ = 0;
				guint8* _tmp23_ = NULL;
				guint8 _tmp24_ = 0U;
				guint8* _tmp25_ = NULL;
				guint8 _tmp26_ = 0U;
				guint8* _tmp27_ = NULL;
				guint8 _tmp28_ = 0U;
				guint8* _tmp29_ = NULL;
				guint8 _tmp30_ = 0U;
				guint8 _tmp31_ = 0U;
				guint8 _tmp35_ = 0U;
				guint8 _tmp36_ = 0U;
				guint8 _tmp37_ = 0U;
				guint8 _tmp38_ = 0U;
				guint8 _tmp39_ = 0U;
				guint8 _tmp40_ = 0U;
				guint8 _tmp41_ = 0U;
				guint8 _tmp42_ = 0U;
				guint8 _tmp43_ = 0U;
				guint8 _tmp44_ = 0U;
				guint8 _tmp45_ = 0U;
				guint8 _tmp46_ = 0U;
				gdouble _tmp47_ = 0.0;
				gdouble _tmp48_ = 0.0;
				gdouble score = 0.0;
				gdouble _tmp51_ = 0.0;
				gdouble _tmp52_ = 0.0;
				guint8 _tmp53_ = 0U;
				guint8 _tmp54_ = 0U;
				gdouble _tmp55_ = 0.0;
				gdouble _tmp56_ = 0.0;
				guint8 _tmp57_ = 0U;
				guint8 _tmp58_ = 0U;
				gdouble _tmp59_ = 0.0;
				gdouble _tmp60_ = 0.0;
				guint8 _tmp61_ = 0U;
				guint8 _tmp62_ = 0U;
				gdouble _tmp63_ = 0.0;
				gdouble _tmp64_ = 0.0;
				gdouble _tmp65_ = 0.0;
				guint8 _tmp66_ = 0U;
				gdouble _tmp67_ = 0.0;
				guint8 _tmp68_ = 0U;
				gdouble _tmp69_ = 0.0;
				guint8 _tmp70_ = 0U;
				gdouble _tmp71_ = 0.0;
				guint8 _tmp72_ = 0U;
				guint8* _tmp73_ = NULL;
				gint _tmp74_ = 0;
				if (!_tmp19_) {
					gint _tmp20_ = 0;
					_tmp20_ = i;
					i = _tmp20_ + 1;
				}
				_tmp19_ = FALSE;
				_tmp21_ = i;
				_tmp22_ = pixels;
				if (!(_tmp21_ < _tmp22_)) {
					break;
				}
				_tmp23_ = dataPtr;
				_tmp24_ = _tmp23_[0];
				r = _tmp24_;
				_tmp25_ = dataPtr;
				_tmp26_ = _tmp25_[1];
				g = _tmp26_;
				_tmp27_ = dataPtr;
				_tmp28_ = _tmp27_[2];
				b = _tmp28_;
				_tmp29_ = dataPtr;
				_tmp30_ = _tmp29_[3];
				a = _tmp30_;
				_tmp31_ = a;
				if (_tmp31_ <= PLANK_DRAWING_DRAWING_SERVICE_ALPHA_THRESHOLD) {
					gint _tmp32_ = 0;
					guint8* _tmp33_ = NULL;
					gint _tmp34_ = 0;
					_tmp32_ = length;
					length = _tmp32_ - 1;
					_tmp33_ = dataPtr;
					_tmp34_ = n_channels;
					dataPtr = _tmp33_ + _tmp34_;
					continue;
				}
				_tmp35_ = r;
				_tmp36_ = g;
				_tmp37_ = b;
				_tmp38_ = MIN (_tmp36_, _tmp37_);
				_tmp39_ = MIN (_tmp35_, _tmp38_);
				min = _tmp39_;
				_tmp40_ = r;
				_tmp41_ = g;
				_tmp42_ = b;
				_tmp43_ = MAX (_tmp41_, _tmp42_);
				_tmp44_ = MAX (_tmp40_, _tmp43_);
				max = _tmp44_;
				_tmp45_ = max;
				_tmp46_ = min;
				delta = (gdouble) (_tmp45_ - _tmp46_);
				_tmp48_ = delta;
				if (_tmp48_ == ((gdouble) 0)) {
					_tmp47_ = 0.0;
				} else {
					gdouble _tmp49_ = 0.0;
					guint8 _tmp50_ = 0U;
					_tmp49_ = delta;
					_tmp50_ = max;
					_tmp47_ = _tmp49_ / _tmp50_;
				}
				score = PLANK_DRAWING_DRAWING_SERVICE_SATURATION_WEIGHT * _tmp47_;
				_tmp51_ = bTotal;
				_tmp52_ = score;
				_tmp53_ = b;
				_tmp54_ = a;
				bTotal = _tmp51_ + ((_tmp52_ * _tmp53_) / _tmp54_);
				_tmp55_ = gTotal;
				_tmp56_ = score;
				_tmp57_ = g;
				_tmp58_ = a;
				gTotal = _tmp55_ + ((_tmp56_ * _tmp57_) / _tmp58_);
				_tmp59_ = rTotal;
				_tmp60_ = score;
				_tmp61_ = r;
				_tmp62_ = a;
				rTotal = _tmp59_ + ((_tmp60_ * _tmp61_) / _tmp62_);
				_tmp63_ = scoreTotal;
				_tmp64_ = score;
				scoreTotal = _tmp63_ + _tmp64_;
				_tmp65_ = bTotal2;
				_tmp66_ = b;
				bTotal2 = _tmp65_ + _tmp66_;
				_tmp67_ = gTotal2;
				_tmp68_ = g;
				gTotal2 = _tmp67_ + _tmp68_;
				_tmp69_ = rTotal2;
				_tmp70_ = r;
				rTotal2 = _tmp69_ + _tmp70_;
				_tmp71_ = aTotal2;
				_tmp72_ = a;
				aTotal2 = _tmp71_ + _tmp72_;
				_tmp73_ = dataPtr;
				_tmp74_ = n_channels;
				dataPtr = _tmp73_ + _tmp74_;
			}
		}
	}
	_tmp75_ = length;
	if (_tmp75_ <= 0) {
		PlankDrawingColor _tmp76_ = {0};
		_tmp76_.R = 0.0;
		_tmp76_.G = 0.0;
		_tmp76_.B = 0.0;
		_tmp76_.A = 0.0;
		*result = _tmp76_;
		return;
	}
	_tmp77_ = scoreTotal;
	_tmp78_ = length;
	scoreTotal = _tmp77_ / _tmp78_;
	_tmp79_ = bTotal;
	_tmp80_ = length;
	bTotal = _tmp79_ / _tmp80_;
	_tmp81_ = gTotal;
	_tmp82_ = length;
	gTotal = _tmp81_ / _tmp82_;
	_tmp83_ = rTotal;
	_tmp84_ = length;
	rTotal = _tmp83_ / _tmp84_;
	_tmp85_ = scoreTotal;
	if (_tmp85_ > 0.0) {
		gdouble _tmp86_ = 0.0;
		gdouble _tmp87_ = 0.0;
		gdouble _tmp88_ = 0.0;
		gdouble _tmp89_ = 0.0;
		gdouble _tmp90_ = 0.0;
		gdouble _tmp91_ = 0.0;
		_tmp86_ = bTotal;
		_tmp87_ = scoreTotal;
		bTotal = _tmp86_ / _tmp87_;
		_tmp88_ = gTotal;
		_tmp89_ = scoreTotal;
		gTotal = _tmp88_ / _tmp89_;
		_tmp90_ = rTotal;
		_tmp91_ = scoreTotal;
		rTotal = _tmp90_ / _tmp91_;
	}
	_tmp92_ = bTotal2;
	_tmp93_ = length;
	_tmp94_ = G_MAXUINT8;
	bTotal2 = _tmp92_ / (_tmp93_ * _tmp94_);
	_tmp95_ = gTotal2;
	_tmp96_ = length;
	_tmp97_ = G_MAXUINT8;
	gTotal2 = _tmp95_ / (_tmp96_ * _tmp97_);
	_tmp98_ = rTotal2;
	_tmp99_ = length;
	_tmp100_ = G_MAXUINT8;
	rTotal2 = _tmp98_ / (_tmp99_ * _tmp100_);
	_tmp101_ = aTotal2;
	_tmp102_ = length;
	_tmp103_ = G_MAXUINT8;
	aTotal2 = _tmp101_ / (_tmp102_ * _tmp103_);
	_tmp104_ = scoreTotal;
	if (_tmp104_ <= PLANK_DRAWING_DRAWING_SERVICE_WEIGHT_THRESHOLD) {
		gdouble f = 0.0;
		gdouble _tmp105_ = 0.0;
		gdouble rf = 0.0;
		gdouble _tmp106_ = 0.0;
		gdouble _tmp107_ = 0.0;
		gdouble _tmp108_ = 0.0;
		gdouble _tmp109_ = 0.0;
		gdouble _tmp110_ = 0.0;
		gdouble _tmp111_ = 0.0;
		gdouble _tmp112_ = 0.0;
		gdouble _tmp113_ = 0.0;
		gdouble _tmp114_ = 0.0;
		gdouble _tmp115_ = 0.0;
		gdouble _tmp116_ = 0.0;
		gdouble _tmp117_ = 0.0;
		gdouble _tmp118_ = 0.0;
		_tmp105_ = scoreTotal;
		f = (1.0 / PLANK_DRAWING_DRAWING_SERVICE_WEIGHT_THRESHOLD) * _tmp105_;
		_tmp106_ = f;
		rf = 1.0 - _tmp106_;
		_tmp107_ = bTotal;
		_tmp108_ = f;
		_tmp109_ = bTotal2;
		_tmp110_ = rf;
		bTotal = (_tmp107_ * _tmp108_) + (_tmp109_ * _tmp110_);
		_tmp111_ = gTotal;
		_tmp112_ = f;
		_tmp113_ = gTotal2;
		_tmp114_ = rf;
		gTotal = (_tmp111_ * _tmp112_) + (_tmp113_ * _tmp114_);
		_tmp115_ = rTotal;
		_tmp116_ = f;
		_tmp117_ = rTotal2;
		_tmp118_ = rf;
		rTotal = (_tmp115_ * _tmp116_) + (_tmp117_ * _tmp118_);
	}
	_tmp119_ = rTotal;
	_tmp120_ = gTotal;
	_tmp121_ = bTotal;
	_tmp122_ = MAX (_tmp120_, _tmp121_);
	_tmp123_ = MAX (_tmp119_, _tmp122_);
	max_val = _tmp123_;
	_tmp124_ = max_val;
	if (_tmp124_ > 1.0) {
		gdouble _tmp125_ = 0.0;
		gdouble _tmp126_ = 0.0;
		gdouble _tmp127_ = 0.0;
		gdouble _tmp128_ = 0.0;
		gdouble _tmp129_ = 0.0;
		gdouble _tmp130_ = 0.0;
		_tmp125_ = bTotal;
		_tmp126_ = max_val;
		bTotal = _tmp125_ / _tmp126_;
		_tmp127_ = gTotal;
		_tmp128_ = max_val;
		gTotal = _tmp127_ / _tmp128_;
		_tmp129_ = rTotal;
		_tmp130_ = max_val;
		rTotal = _tmp129_ / _tmp130_;
	}
	_tmp131_ = rTotal;
	_tmp132_ = gTotal;
	_tmp133_ = bTotal;
	_tmp134_ = aTotal2;
	_tmp135_.R = _tmp131_;
	_tmp135_.G = _tmp132_;
	_tmp135_.B = _tmp133_;
	_tmp135_.A = _tmp134_;
	*result = _tmp135_;
	return;
}
Esempio n. 5
0
static GdkPixbuf* calc_alpha_from_pixbufs(GdkPixbuf *p_pb_black, GdkPixbuf *p_pb_white)
{
	guchar* t_black_ptr;
	guchar* t_white_ptr;
	int t_black_stride;
	int t_white_stride;
    int t_black_channels;
    int t_white_channels;
	
	int t_w, t_h;
	
	t_w = gdk_pixbuf_get_width(p_pb_black);
    t_h = gdk_pixbuf_get_height(p_pb_black);
    
    t_black_stride = gdk_pixbuf_get_rowstride(p_pb_black);
    t_white_stride = gdk_pixbuf_get_rowstride(p_pb_white);
    
    t_black_channels = gdk_pixbuf_get_n_channels(p_pb_black);
    t_white_channels = gdk_pixbuf_get_n_channels(p_pb_white);
	
	/*
		Formula for calculating the alpha of the source, by 
		rendering it twice - once against black, the second time
		agaist white.
	
			Dc' = Sc.Sa + (1 - Sa) * Dc

			composite against black (Dc == 0):
			Dc'b = Sc.Sa => Dc'b <= Sa

			composite against white (Dc == 1.0)
			Dc'w = Sc.Sa + (1 - Sa)

			Sa = 1 - (Dc'w - Dc'b)
			Sc.Sa = Dc'b
	
			As Sc=Dc'b all we need to actually do is recalculate the alpha byte for the black image.
	*/
	
	uint8_t rb, rw;
	uint8_t na;
	int x, y;
	
	for ( y = 0 ; y < t_h; y ++ )
	{
		for ( x = 0 ; x < t_w ; x++ )
		{	
			t_white_ptr = gdk_pixbuf_get_pixels(p_pb_white) + (t_white_stride * y) + (t_white_channels * x);
            t_black_ptr = gdk_pixbuf_get_pixels(p_pb_black) + (t_black_stride * y) + (t_black_channels * x);

			rb = *(t_black_ptr);
			rw = *(t_white_ptr);
			
			na = uint8_t(255 - rw + rb);
			*(t_black_ptr + 3) = na;
		}
	}
	
	g_object_unref(p_pb_white);
	
	return p_pb_black;
}
Esempio n. 6
0
CoglBitmap *
_cogl_bitmap_from_file (const char   *filename,
			GError      **error)
{
  static CoglUserDataKey pixbuf_key;
  GdkPixbuf        *pixbuf;
  CoglBool          has_alpha;
  GdkColorspace     color_space;
  CoglPixelFormat   pixel_format;
  int               width;
  int               height;
  int               rowstride;
  int               bits_per_sample;
  int               n_channels;
  CoglBitmap       *bmp;

  _COGL_GET_CONTEXT (ctx, NULL);

  _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, FALSE);

  /* Load from file using GdkPixbuf */
  pixbuf = gdk_pixbuf_new_from_file (filename, error);
  if (pixbuf == NULL)
    return FALSE;

  /* Get pixbuf properties */
  has_alpha       = gdk_pixbuf_get_has_alpha (pixbuf);
  color_space     = gdk_pixbuf_get_colorspace (pixbuf);
  width           = gdk_pixbuf_get_width (pixbuf);
  height          = gdk_pixbuf_get_height (pixbuf);
  rowstride       = gdk_pixbuf_get_rowstride (pixbuf);
  bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
  n_channels      = gdk_pixbuf_get_n_channels (pixbuf);

  /* According to current docs this should be true and so
   * the translation to cogl pixel format below valid */
  g_assert (bits_per_sample == 8);

  if (has_alpha)
    g_assert (n_channels == 4);
  else
    g_assert (n_channels == 3);

  /* Translate to cogl pixel format */
  switch (color_space)
    {
    case GDK_COLORSPACE_RGB:
      /* The only format supported by GdkPixbuf so far */
      pixel_format = has_alpha ?
	COGL_PIXEL_FORMAT_RGBA_8888 :
	COGL_PIXEL_FORMAT_RGB_888;
      break;

    default:
      /* Ouch, spec changed! */
      g_object_unref (pixbuf);
      return FALSE;
    }

  /* We just use the data directly from the pixbuf so that we don't
     have to copy to a seperate buffer. Note that Cogl is expected not
     to read past the end of bpp*width on the last row even if the
     rowstride is much larger so we don't need to worry about
     GdkPixbuf's semantics that it may under-allocate the buffer. */
  bmp = cogl_bitmap_new_for_data (ctx,
                                  width,
                                  height,
                                  pixel_format,
                                  rowstride,
                                  gdk_pixbuf_get_pixels (pixbuf));

  cogl_object_set_user_data (COGL_OBJECT (bmp),
                             &pixbuf_key,
                             pixbuf,
                             g_object_unref);

  return bmp;
}
Esempio n. 7
0
/* print a GdkPixbuf to cairo at the specified position and with the
 * specified scale */
gboolean
cairo_print_pixbuf(cairo_t * cairo_ctx, const GdkPixbuf * pixbuf,
		   gdouble c_at_x, gdouble c_at_y, gdouble scale)
{
    guchar *raw_image;
    gint n_chans;
    guint32 *surface_buf;
    gint width;
    gint height;
    gint rowstride;
    guint32 *dest;
    cairo_format_t format;
    cairo_surface_t *surface;
    cairo_pattern_t *pattern;
    cairo_matrix_t matrix;

    /* paranoia checks */
    g_return_val_if_fail(cairo_ctx && pixbuf, FALSE);

    /* must have 8 bpp */
    g_return_val_if_fail(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8,
			 FALSE);

    /* must have 3 (no alpha) or 4 (with alpha) channels */
    n_chans = gdk_pixbuf_get_n_channels(pixbuf);
    g_return_val_if_fail(n_chans == 3 || n_chans == 4, FALSE);

    /* allocate a new buffer */
    /* FIXME: does this work on 64 bit machines if the witdth is odd? */
    width = gdk_pixbuf_get_width(pixbuf);
    height = gdk_pixbuf_get_height(pixbuf);
    if (!(surface_buf = g_new0(guint32, width * height)))
	return FALSE;

    /* copy pixbuf to a cairo buffer */
    dest = surface_buf;
    raw_image = gdk_pixbuf_get_pixels(pixbuf);
    rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    if (n_chans == 4) {
	/* 4 channels: copy 32-bit vals, converting R-G-B-Alpha to
	 * Alpha-R-G-B... */
	gint line;

	format = CAIRO_FORMAT_ARGB32;
	for (line = 0; line < height; line++) {
	    guchar *src = raw_image + line * rowstride;
	    gint col;

	    for (col = width; col; col--, src += 4)
		*dest++ = (((((src[3] << 8) + src[0]) << 8) + src[1]) << 8) + src[2];
	}
    } else {
	/* 3 channels: copy 3 byte R-G-B to Alpha-R-G-B... */
	gint line;

	format = CAIRO_FORMAT_RGB24;
	for (line = 0; line < height; line++) {
	    guchar *src = raw_image + line * rowstride;
	    gint col;

	    for (col = width; col; col--, src += 3)
		*dest++ = (((src[0] << 8) + src[1]) << 8) + src[2];
	}
    }

    /* save current state */
    cairo_save(cairo_ctx);

    /* create the curface */
    surface =
	cairo_image_surface_create_for_data((unsigned char *) surface_buf,
					    format, width, height,
					    4 * width);
    cairo_set_source_surface(cairo_ctx, surface, c_at_x, c_at_y);

    /* scale */
    pattern = cairo_get_source(cairo_ctx);
    cairo_pattern_get_matrix(pattern, &matrix);
    matrix.xx /= scale;
    matrix.yy /= scale;
    matrix.x0 /= scale;
    matrix.y0 /= scale;
    cairo_pattern_set_matrix(pattern, &matrix);

    /* clip around the image */
    cairo_new_path(cairo_ctx);
    cairo_move_to(cairo_ctx, c_at_x, c_at_y);
    cairo_line_to(cairo_ctx, c_at_x + width * scale, c_at_y);
    cairo_line_to(cairo_ctx, c_at_x + width * scale,
		  c_at_y + height * scale);
    cairo_line_to(cairo_ctx, c_at_x, c_at_y + height * scale);
    cairo_close_path(cairo_ctx);
    cairo_clip(cairo_ctx);

    /* paint, restore and clean up */
    cairo_paint(cairo_ctx);
    cairo_restore(cairo_ctx);
    cairo_surface_destroy(surface);
    g_free(surface_buf);

    return TRUE;
}
Esempio n. 8
0
/*! This method is used to read the image file and copy it to a 
 * pixel buffer which will then be used to greate the underlying grid representation
 * of the map.
 */
int Map::readMapFile(char * filename)
{
  	guchar* pixels;
  	guchar* p;
  	int rowstride, n_channels, bps;
  	GError* error = NULL;
  	int i,j,k;
  	double occ;
  	int color_sum;
  	double color_avg;
  	this->mapFileName = filename;
    g_type_init();
  	printf("\nMapFile loading image file: %s...", this->mapFileName);
  	fflush(stdout);

  	// Read the image
  	if(!(pixbuf = gdk_pixbuf_new_from_file(this->mapFileName, &error)))
  	{
    	printf("\nfailed to open image file %s", this->mapFileName);
    	return(-1);
  	}
	this->drawingPixBuf = gdk_pixbuf_copy(this->pixbuf);
  	this->width = gdk_pixbuf_get_width(pixbuf);
  	this->height = gdk_pixbuf_get_height(pixbuf);

	allocateGrid();

 	rowstride = gdk_pixbuf_get_rowstride(pixbuf);
  	bps = gdk_pixbuf_get_bits_per_sample(pixbuf)/8;
  	n_channels = gdk_pixbuf_get_n_channels(pixbuf);
  	if(gdk_pixbuf_get_has_alpha(pixbuf))
    	n_channels++;
  	// Read data
  	pixels = gdk_pixbuf_get_pixels(pixbuf);
  	int count =0;
  	for(j = 0; j < this->height; j++)
  	{
    	for (i = 0; i < this->width; i++)
    	{
      		p = pixels + j*rowstride + i*n_channels*bps;
      		color_sum = 0;
      		for(k=0;k<n_channels;k++)
        		color_sum += *(p + (k * bps));
      		color_avg = color_sum / (double)n_channels;

      		if(this->negate)
        		occ = color_avg / 255.0;
      		else
        		occ = (255 - color_avg) / 255.0;
      		if(occ < 0.1)
      		{
        		this->grid[i][j] = 0;
      		}
	  		else
	  		{
	  			this->grid[i][j] = 1;
	  			count++;
	  		}
    	}
  	}
  	printf("\nMapFile read a %d X %d map, at %.3f m/pix",this->width, this->height, this->mapRes); fflush(stdout);
  	return(0);	
};
Esempio n. 9
0
static nsresult
moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI,
                          nsIChannel **aChannel)
{
  int width = gdk_pixbuf_get_width(aPixbuf);
  int height = gdk_pixbuf_get_height(aPixbuf);
  NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
                 gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB &&
                 gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 &&
                 gdk_pixbuf_get_has_alpha(aPixbuf) &&
                 gdk_pixbuf_get_n_channels(aPixbuf) == 4,
                 NS_ERROR_UNEXPECTED);

  const int n_channels = 4;
  gsize buf_size = 2 + n_channels * height * width;
  PRUint8 * const buf = (PRUint8*)NS_Alloc(buf_size);
  NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
  PRUint8 *out = buf;

  *(out++) = width;
  *(out++) = height;

  const guchar * const pixels = gdk_pixbuf_get_pixels(aPixbuf);
  int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels;

  // encode the RGB data and the A data
  const guchar * in = pixels;
  for (int y = 0; y < height; ++y, in += rowextra) {
    for (int x = 0; x < width; ++x) {
      PRUint8 r = *(in++);
      PRUint8 g = *(in++);
      PRUint8 b = *(in++);
      PRUint8 a = *(in++);
#define DO_PREMULTIPLY(c_) PRUint8(PRUint16(c_) * PRUint16(a) / PRUint16(255))
#ifdef IS_LITTLE_ENDIAN
      *(out++) = DO_PREMULTIPLY(b);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = a;
#else
      *(out++) = a;
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(b);
#endif
#undef DO_PREMULTIPLY
    }
  }

  NS_ASSERTION(out == buf + buf_size, "size miscalculation");

  nsresult rv;
  nsCOMPtr<nsIStringInputStream> stream =
    do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = stream->AdoptData((char*)buf, buf_size);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = NS_NewInputStreamChannel(aChannel, aURI, stream,
                                NS_LITERAL_CSTRING("image/icon"));
  return rv;
}
Esempio n. 10
0
static void
_vte_gl_clear(struct _vte_draw *draw, gint x, gint y, gint width, gint height)
{
	struct _vte_gl_data *data = draw->impl_data;
	long xstop, ystop, i, j;
	int pixbufw, pixbufh, w, h, channels, stride;
	GLenum format = 0;
	guchar *pixels;

	glXMakeCurrent(data->display, data->glwindow, data->context);

	if (data->bgpixbuf != NULL) {
		pixbufw = gdk_pixbuf_get_width(data->bgpixbuf);
		pixbufh = gdk_pixbuf_get_height(data->bgpixbuf);
	} else {
		pixbufw = pixbufh = 0;
	}

	if ((pixbufw == 0) || (pixbufh == 0)) {
		glColor4us(draw->bg_color.red,
			   draw->bg_color.green,
			   draw->bg_color.blue,
			   0xFFFF);
		glBegin(GL_POLYGON);
		glVertex2d(x, y);
		glVertex2d(x + width, y);
		glVertex2d(x + width, y + height - 1);
		glVertex2d(x, y + height - 1);
		glEnd();
		return;
	}

	/* Flood fill. */
	xstop = x + width;
	ystop = y + height;

	pixels = gdk_pixbuf_get_pixels(data->bgpixbuf);
	channels = gdk_pixbuf_get_n_channels(data->bgpixbuf);
	stride = gdk_pixbuf_get_rowstride(data->bgpixbuf);

	switch (channels) {
	case 3:
		format = GL_RGB;
		break;
	case 4:
		format = GL_RGBA;
		break;
	default:
		g_assert_not_reached();
		break;
	}

	y = ystop - height;
	j = (draw->scrolly + y) % pixbufh;
	while (y < ystop) {
		x = xstop - width;
		i = (draw->scrollx + x) % pixbufw;

		/* h = MIN(pixbufh - (j % pixbufh), ystop - y); */
		h = 1;
		while (x < xstop) {
			w = MIN(pixbufw - (i % pixbufw), xstop - x);

			glRasterPos2i(x, y);
			glDrawPixels(w, h,
				     format, GL_UNSIGNED_BYTE,
				     pixels + stride * j + channels * i);
			x += w;
			i = 0;
		}
		y += h;
		j = (draw->scrolly + y) % pixbufh;
	}
	glFlush();
}
Esempio n. 11
0
carmen_map_p carmen_pixbuf_to_map(GdkPixbuf* pixbuf, double resolution )
{
  carmen_map_p map;
  int x_index, y_index;
  int rowstride, n_channels;
  guchar *pixels, *p;

  if (pixbuf == NULL) {
    carmen_warn("Error: im = NULL in %s at line %d in file %s\n",
		__FUNCTION__, __LINE__, __FILE__);
    return NULL;
  }

  if (gdk_pixbuf_get_colorspace (pixbuf) != GDK_COLORSPACE_RGB) {
    carmen_warn("File is not RGB colorspace. carmen_pixbuf_to_map failed\n");
    return NULL;
  }

  if (gdk_pixbuf_get_bits_per_sample (pixbuf) != 8) {
    carmen_warn("File is not 8 bits per pixel. carmen_pixbuf_to_map failed\n");
    return NULL;
  }

  if (gdk_pixbuf_get_has_alpha (pixbuf) == 1) {
    carmen_warn("File has alpha channel. carmen_pixbuf_to_map failed\n");
    return NULL;
  }

  n_channels = gdk_pixbuf_get_n_channels (pixbuf);
  if (n_channels != 3) {
    carmen_warn("File has alpha channel. carmen_pixbuf_to_map failed\n");
    return NULL;
  }

  map = (carmen_map_p)calloc(1, sizeof(carmen_map_t));
  carmen_test_alloc(map);

  map->config.x_size = gdk_pixbuf_get_width(pixbuf);
  map->config.y_size = gdk_pixbuf_get_height(pixbuf);
  map->config.resolution =  resolution;

  map->complete_map = (float *)
    calloc(map->config.x_size*map->config.y_size, sizeof(float));
  carmen_test_alloc(map->complete_map);
  
  map->map = (float **)calloc(map->config.x_size, sizeof(float *));
  carmen_test_alloc(map->map);
  for (x_index = 0; x_index < map->config.x_size; x_index++) 
    map->map[x_index] = map->complete_map+x_index*map->config.y_size;

  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  pixels = gdk_pixbuf_get_pixels (pixbuf);

  for (x_index = 0; x_index < map->config.x_size; x_index++) 
    for (y_index = 0; y_index < map->config.y_size; y_index++) {
      unsigned char r,g ,b;
      p = pixels + y_index * rowstride + x_index * n_channels;
      r = p[0];
      g = p[1];
      b = p[2];
      
      if (carmen_map_image_to_map_color_unknown(r,g,b)) 
	map->map[x_index][map->config.y_size-1-y_index] = -1.0;
      else if (r==255 && g==0 && b==0) { // offlimits
        map->map[x_index][map->config.y_size-1-y_index] = -2.0;
      }
      else 
	map->map[x_index][map->config.y_size-1-y_index] =  
	  carmen_map_image_to_map_color_occupancy(r,g,b);
    }
  return map;
}
static GstFlowReturn
gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter)
{
  GstBuffer *outbuf;
  GdkPixbuf *pixbuf;
  int y;
  guint8 *out_pix;
  guint8 *in_pix;
  int in_rowstride, out_rowstride;
  GstFlowReturn ret;
  GstCaps *caps = NULL;
  gint width, height;
  gint n_channels;
  GstVideoFrame frame;

  pixbuf = gdk_pixbuf_loader_get_pixbuf (filter->pixbuf_loader);
  if (pixbuf == NULL)
    goto no_pixbuf;

  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  if (GST_VIDEO_INFO_FORMAT (&filter->info) == GST_VIDEO_FORMAT_UNKNOWN) {
    GstVideoInfo info;
    GstVideoFormat fmt;

    GST_DEBUG ("Set size to %dx%d", width, height);

    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
    switch (n_channels) {
      case 3:
        fmt = GST_VIDEO_FORMAT_RGB;
        break;
      case 4:
        fmt = GST_VIDEO_FORMAT_RGBA;
        break;
      default:
        goto channels_not_supported;
    }


    gst_video_info_init (&info);
    gst_video_info_set_format (&info, fmt, width, height);
    info.fps_n = filter->in_fps_n;
    info.fps_d = filter->in_fps_d;
    caps = gst_video_info_to_caps (&info);

    filter->info = info;

    gst_pad_set_caps (filter->srcpad, caps);
    gst_caps_unref (caps);

    gst_gdk_pixbuf_dec_setup_pool (filter, &info);
  }

  ret = gst_buffer_pool_acquire_buffer (filter->pool, &outbuf, NULL);
  if (ret != GST_FLOW_OK)
    goto no_buffer;

  GST_BUFFER_TIMESTAMP (outbuf) = filter->last_timestamp;
  GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;

  in_pix = gdk_pixbuf_get_pixels (pixbuf);
  in_rowstride = gdk_pixbuf_get_rowstride (pixbuf);

  gst_video_frame_map (&frame, &filter->info, outbuf, GST_MAP_WRITE);
  out_pix = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
  out_rowstride = GST_VIDEO_FRAME_PLANE_STRIDE (&frame, 0);

  for (y = 0; y < height; y++) {
    memcpy (out_pix, in_pix, width * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, 0));
    in_pix += in_rowstride;
    out_pix += out_rowstride;
  }

  gst_video_frame_unmap (&frame);

  GST_DEBUG ("pushing... %" G_GSIZE_FORMAT " bytes",
      gst_buffer_get_size (outbuf));
  ret = gst_pad_push (filter->srcpad, outbuf);

  if (ret != GST_FLOW_OK)
    GST_DEBUG_OBJECT (filter, "flow: %s", gst_flow_get_name (ret));

  return ret;

  /* ERRORS */
no_pixbuf:
  {
    GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL), ("error geting pixbuf"));
    return GST_FLOW_ERROR;
  }
channels_not_supported:
  {
    GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL),
        ("%d channels not supported", n_channels));
    return GST_FLOW_ERROR;
  }
no_buffer:
  {
    GST_DEBUG ("Failed to create outbuffer - %s", gst_flow_get_name (ret));
    return ret;
  }
}
Esempio n. 13
0
/**
 * gdk_pixbuf_render_threshold_alpha:
 * @pixbuf: A pixbuf.
 * @bitmap: Bitmap where the bilevel mask will be painted to.
 * @src_x: Source X coordinate.
 * @src_y: source Y coordinate.
 * @dest_x: Destination X coordinate.
 * @dest_y: Destination Y coordinate.
 * @width: Width of region to threshold, or -1 to use pixbuf width
 * @height: Height of region to threshold, or -1 to use pixbuf height
 * @alpha_threshold: Opacity values below this will be painted as zero; all
 * other values will be painted as one.
 *
 * Takes the opacity values in a rectangular portion of a pixbuf and thresholds
 * them to produce a bi-level alpha mask that can be used as a clipping mask for
 * a drawable.
 *
 **/
void
gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf,
                                   GdkBitmap *bitmap,
                                   int        src_x,
                                   int        src_y,
                                   int        dest_x,
                                   int        dest_y,
                                   int        width,
                                   int        height,
                                   int        alpha_threshold)
{
  GdkGC *gc;
  GdkColor color;
  int x, y;
  guchar *p;
  int start, start_status;
  int status;

  g_return_if_fail (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
  g_return_if_fail (gdk_pixbuf_get_n_channels (pixbuf) == 3 ||
                        gdk_pixbuf_get_n_channels (pixbuf) == 4);
  g_return_if_fail (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);

  if (width == -1) 
    width = gdk_pixbuf_get_width (pixbuf);
  if (height == -1)
    height = gdk_pixbuf_get_height (pixbuf);

  g_return_if_fail (bitmap != NULL);
  g_return_if_fail (width >= 0 && height >= 0);
  g_return_if_fail (src_x >= 0 && src_x + width <= gdk_pixbuf_get_width (pixbuf));
  g_return_if_fail (src_y >= 0 && src_y + height <= gdk_pixbuf_get_height (pixbuf));

  g_return_if_fail (alpha_threshold >= 0 && alpha_threshold <= 255);

  if (width == 0 || height == 0)
    return;

  gc = _gdk_drawable_get_scratch_gc (bitmap, FALSE);

  if (!gdk_pixbuf_get_has_alpha (pixbuf))
    {
      color.pixel = (alpha_threshold == 255) ? 0 : 1;
      gdk_gc_set_foreground (gc, &color);
      gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height);
      return;
    }

  color.pixel = 0;
  gdk_gc_set_foreground (gc, &color);
  gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height);

  color.pixel = 1;
  gdk_gc_set_foreground (gc, &color);

  for (y = 0; y < height; y++)
    {
      p = (gdk_pixbuf_get_pixels (pixbuf) + (y + src_y) * gdk_pixbuf_get_rowstride (pixbuf) + src_x * gdk_pixbuf_get_n_channels (pixbuf)
	   + gdk_pixbuf_get_n_channels (pixbuf) - 1);
	    
      start = 0;
      start_status = *p < alpha_threshold;
	    
      for (x = 0; x < width; x++)
	{
	  status = *p < alpha_threshold;
	  
	  if (status != start_status)
	    {
	      if (!start_status)
		gdk_draw_line (bitmap, gc,
			       start + dest_x, y + dest_y,
			       x - 1 + dest_x, y + dest_y);
	      
	      start = x;
	      start_status = status;
	    }
	  
	  p += gdk_pixbuf_get_n_channels (pixbuf);
	}
      
      if (!start_status)
	gdk_draw_line (bitmap, gc,
		       start + dest_x, y + dest_y,
		       x - 1 + dest_x, y + dest_y);
    }
}
Esempio n. 14
0
static CoglHandle
cinnamon_app_create_faded_icon_cpu (StTextureCache *cache,
                                 const char     *key,
                                 void           *datap,
                                 GError        **error)
{
  ClutterBackend *backend = clutter_get_default_backend ();
  CoglContext *ctx = clutter_backend_get_cogl_context (backend);
  CreateFadedIconData *data = datap;
  CinnamonApp *app;
  GdkPixbuf *pixbuf;
  int size;
  int scale;
  CoglHandle texture;
  gint width, height, rowstride;
  guint8 n_channels;
  gboolean have_alpha;
  gint fade_start;
  gint fade_range;
  guint i, j;
  guint pixbuf_byte_size;
  guint8 *orig_pixels;
  guint8 *pixels;
  GIcon *icon;
  GtkIconInfo *info;

  app = data->app;
  size = data->size;
  scale = data->scale;

  info = NULL;

  icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
  if (icon != NULL)
    {
      info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
                                                       icon, size, scale,
                                                       GTK_ICON_LOOKUP_FORCE_SIZE);
    }

  if (info == NULL)
    {
      icon = g_themed_icon_new ("application-x-executable");
      info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (),
                                                       icon, size, scale,
                                                       GTK_ICON_LOOKUP_FORCE_SIZE);
      g_object_unref (icon);
    }

  if (info == NULL)
    return COGL_INVALID_HANDLE;

  pixbuf = gtk_icon_info_load_icon (info, NULL);
  gtk_icon_info_free (info);

  if (pixbuf == NULL)
    return COGL_INVALID_HANDLE;

  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  n_channels = gdk_pixbuf_get_n_channels (pixbuf);
  orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
  have_alpha = gdk_pixbuf_get_has_alpha (pixbuf);

  pixbuf_byte_size = (height - 1) * rowstride +
    + width * ((n_channels * gdk_pixbuf_get_bits_per_sample (pixbuf) + 7) / 8);

  pixels = g_malloc0 (rowstride * height);
  memcpy (pixels, orig_pixels, pixbuf_byte_size);

  fade_start = width / 2;
  fade_range = width - fade_start;
  for (i = fade_start; i < width; i++)
    {
      for (j = 0; j < height; j++)
        {
          guchar *pixel = &pixels[j * rowstride + i * n_channels];
          float fade = 1.0 - ((float) i - fade_start) / fade_range;
          pixel[0] = 0.5 + pixel[0] * fade;
          pixel[1] = 0.5 + pixel[1] * fade;
          pixel[2] = 0.5 + pixel[2] * fade;
          if (have_alpha)
            pixel[3] = 0.5 + pixel[3] * fade;
        }
    }

  texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
                                                         have_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
#if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0)
                                                         COGL_PIXEL_FORMAT_ANY,
#endif
                                                         rowstride,
                                                         pixels,
                                                         NULL));
  g_free (pixels);
  g_object_unref (pixbuf);

  return texture;
}
Esempio n. 15
0
static void draw(M6502 *mpu, GdkPixbuf *pixbuf)
{
    Strudel *mb = (Strudel *) mpu->ext;

    int pixel[7];
    guchar *p = NULL;

    int channels = 0;
    int width = 0;
    int ri = 0;
    int rs = 0;

    int byte = 0;
    int c = 0;
    int col = 0;
    int d = 0;
    int maxcol = 40;
    int maxd = 2;
    int x = 0;
    int y = 0;

    int addr = 0;
    int black = 0;
    int offset = 0;
    int palette = 0;
    int previous = 0;
	int dirty = 1;

    int line = 0;
    int group = 0;
    int third = 0;

	int hrpbase = 8192;
    int tlpbase = 1024;

    channels = gdk_pixbuf_get_n_channels(pixbuf);
    width = gdk_pixbuf_get_width(pixbuf);
    rs = gdk_pixbuf_get_rowstride(pixbuf);
    ri = rs - width * channels;

    p = gdk_pixbuf_get_pixels(pixbuf);

    if (mb->rd80col) {
        maxcol = 80;
        maxd = 1;
    }

	if (!mb->rd80store && mb->rdpage2) {
		hrpbase = 16384;
    	tlpbase = 2048;
	}

    if (mb->rdtext)
        goto text;
    else if (!mb->rdhires)
        goto lores;
    else if (!mb->rddhires)
      	goto hires;

    for (third = 0; third < 3; third++) {
        for (group = 0; group < 8; group++) {

            y = third * 64 + group * 8;
            if (mb->rdmixed && y >= 160)
                goto text;

            for (line = 0; line < 8; line++, p = next(p + ri, dirty, rs)) {
                addr = line * 1024 + group * 128 + third * 40;
				dirty = hrpupd[third] & (1 << (line * 8 + group));
				if (!dirty) {
					p += rs;
					continue;
				}
				addr += hrpbase;

                for (col = 0; col < 40; col+=2) {

                    pixel[0] = mb->aux[addr + col] % 16;
                    pixel[1] = (mb->aux[addr + col] / 16) % 8 +
                               (mb->main[addr + col] % 2) * 8;
                    pixel[2] = (mb->main[addr + col] / 2) % 16;
                    pixel[3] = (mb->main[addr + col] / 32) % 4 +
                               (mb->aux[addr + col + 1] % 4) * 4;
                    pixel[4] = (mb->aux[addr + col + 1] / 4) % 16;
                    pixel[5] = (mb->aux[addr + col + 1] / 64) % 2 +
                               (mb->main[addr + col + 1] % 8) * 2;
                    pixel[6] = (mb->main[addr + col + 1] / 8) % 16;

                    for (x = 0; x < 7; x++, p += channels * 2) {
                        p[0] = color[pixel[x]][0];
                        p[1] = color[pixel[x]][1];
                        p[2] = color[pixel[x]][2];
                        p[3] = color[pixel[x]][0];
                        p[4] = color[pixel[x]][1];
                        p[5] = color[pixel[x]][2];
                    }
                }
            }
        }
    }

    return;


hires:
    for (third = 0; third < 3; third++) {
        for (group = 0; group < 8; group++) {

            y = third * 64 + group * 8;
            if (mb->rdmixed && y >= 160)
                goto text;

            for (line = 0; line < 8; line++, p = next(p + ri, dirty, rs)) {
                addr = line * 1024 + group * 128 + third * 40;
				dirty = hrpupd[third] & (1 << (line * 8 + group));
				if (!dirty) {
					p += rs;
					continue;
				}
				addr += hrpbase;

                black = 0;
                previous = 0;

                for (col = 0; col < 40; col++) {

                    byte = mb->main[addr + col];
                    palette = byte / 128;

                    for (x = 0; x < 7; x++, p += channels * 2) {
                        if (byte % 2) {
                            if (previous && !black) {
                                c = 15;
                            } else {
                                c = hcolor[palette * 2 +
                                           ((x % 2 == col % 2) ? 0 : 1)];
                            }
                        } else {
                            c = 0;
                            black++;
                        }

                        if (previous == c && black < 2) {
                           p[-6] = color[c][0];
                           p[-5] = color[c][1];
                           p[-4] = color[c][2];
                           p[-3] = color[c][0];
                           p[-2] = color[c][1];
                           p[-1] = color[c][2];
                        }

                        p[0 + palette * 3] = color[c][0];
                        p[1 + palette * 3] = color[c][1];
                        p[2 + palette * 3] = color[c][2];
                        p[3 - palette * 3] = color[c][0];
                        p[4 - palette * 3] = color[c][1];
                        p[5 - palette * 3] = color[c][2];

                        if (c) {
                            black = 0;
                            previous = c;
                        }

                        byte = byte / 2;
                    }
                }
            }
        }
    }

    return;


lores:
    for (third = 0; third < 3; third++) {
        for (group = 0; group < 8; group++) {
            y = third * 64 + group * 8;
            if (mb->rdmixed && y >= 160)
                goto text;

            addr = group * 128 + third * 40;
			dirty = tlpupd[third] & (1 << group);
			if (!dirty) {
				p += 16 * rs;
				continue;
			}
			addr += tlpbase;

            for (line = 0; line < 8; line++, p = next(p + ri, dirty, rs)) {
                for (col = 0; col < maxcol; col++) {

                    if (mb->rd80col) {
                       c = ((col % 2) ? mb->main : mb->aux)[addr + col / 2];
                    } else {
                       c = mb->main[addr + col];
                    }
                    if (line >= 4)
                        c /= 16;
                    c %= 16;

                    for (x = 0; x < 7; x++, offset += channels) {
                        for (d = 0; d < maxd; d++, p += channels) {
                            p[0] = color[c][0];
                            p[1] = color[c][1];
                            p[2] = color[c][2];
                        }
                    }
                }
            }
        }
    }

    return;


    for (third = 0; third < 3; third++) {
        for (group = 0; group < 8; group++) {

text:
            addr = group * 128 + third * 40;
			dirty = tlpupd[third] & (1 << group);
			if (!dirty) {
				p += 16 * rs;
				continue;
			}
			addr += tlpbase;

            for (line = 0; line < 8; line++, p = next(p + ri, dirty, rs)) {
                for (col = 0; col < maxcol; col++) {

                    if (mb->rd80col) {
                       c = ((col % 2) ? mb->main : mb->aux)[addr + col / 2];
                    } else {
                       c = mb->main[addr + col];
                    }

                    p += display(mb, maxd, line, c, p);
                }
            }
        }
    }


    return;
}
/**
 * gs_plugin_key_colors_set_for_pixbuf:
 */
static void
gs_plugin_key_colors_set_for_pixbuf (GsApp *app, GdkPixbuf *pb, guint number)
{
	GList *l;
	gint rowstride, n_channels;
	gint x, y;
	guchar *pixels, *p;
	guint bin_size = 200;
	guint i;
	guint number_of_bins;
	g_autoptr(AsImage) im = NULL;

	/* go through each pixel */
	n_channels = gdk_pixbuf_get_n_channels (pb);
	rowstride = gdk_pixbuf_get_rowstride (pb);
	pixels = gdk_pixbuf_get_pixels (pb);
	for (bin_size = 250; bin_size > 0; bin_size -= 2) {
		g_autoptr(GHashTable) hash = NULL;
		hash = g_hash_table_new_full (g_direct_hash,  g_direct_equal,
					      NULL, g_free);
		for (y = 0; y < gdk_pixbuf_get_height (pb); y++) {
			for (x = 0; x < gdk_pixbuf_get_width (pb); x++) {
				CdColorRGB8 tmp;
				GsColorBin *s;
				gpointer key;

				/* disregard any with alpha */
				p = pixels + y * rowstride + x * n_channels;
				if (p[3] != 255)
					continue;

				/* find in cache */
				tmp.R = p[0] / bin_size;
				tmp.G = p[1] / bin_size;
				tmp.B = p[2] / bin_size;
				key = GUINT_TO_POINTER (cd_color_rgb8_to_uint32 (&tmp));
				s = g_hash_table_lookup (hash, key);
				if (s != NULL) {
					s->color.red += p[0];
					s->color.green += p[1];
					s->color.blue += p[2];
					s->cnt++;
					continue;
				}

				/* add to hash table */
				s = g_new0 (GsColorBin, 1);
				s->color.red = p[0];
				s->color.green = p[1];
				s->color.blue = p[2];
				s->color.alpha = 1.0;
				s->cnt = 1;
				g_hash_table_insert (hash, key, s);
			}
		}

		number_of_bins = g_hash_table_size (hash);
//		g_debug ("number of colors: %i", number_of_bins);
		if (number_of_bins >= number) {
			g_autoptr(GList) values = NULL;

			/* order by most popular */
			values = g_hash_table_get_values (hash);
			values = g_list_sort (values, gs_color_bin_sort_cb);
			for (l = values; l != NULL; l = l->next) {
				GsColorBin *s = l->data;
				g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1);
				color->red = s->color.red / s->cnt;
				color->green = s->color.green / s->cnt;
				color->blue = s->color.blue / s->cnt;
				gs_app_add_key_color (app, color);
			}
			return;
		}
	}

	/* the algorithm failed, so just return a monochrome ramp */
	for (i = 0; i < 3; i++) {
		g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1);
		color->red = 255 * i / 3;
		color->green = color->red;
		color->blue = color->red;
		color->alpha = 1.0f;
		gs_app_add_key_color (app, color);
	}
}
Esempio n. 17
0
GdkPixbuf *
pv_gdk_pixbuf_rotate_simple (const GdkPixbuf   *src,
			  GdkPixbufRotation angle)
{
  GdkPixbuf *dest;
  guchar *p, *q;
  gint x, y;
  int srcwidth=gdk_pixbuf_get_width(src);
  int srcheight=gdk_pixbuf_get_height(src);

  switch (angle % 360)
    {
    case 0:
      dest = gdk_pixbuf_copy (src);
      break;
    case 90:
      dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace(src), 
			     gdk_pixbuf_get_has_alpha(src),
			     gdk_pixbuf_get_bits_per_sample(src), 
			     srcheight,srcwidth);
      if (!dest)
	return NULL;

      for (y = 0; y < srcheight; y++) 
	{ 
	  for (x = 0; x < srcwidth; x++) 
	    { 
	      p = gdk_pixbuf_get_pixels(src) + OFFSET (src, x, y); 
	      q = gdk_pixbuf_get_pixels(dest) + OFFSET (dest, y, srcwidth - x - 1); 
	      memcpy (q, p, gdk_pixbuf_get_n_channels(dest));
	    }
	} 
      break;
    case 180:
      dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace(src), 
			     gdk_pixbuf_get_has_alpha(src),
			     gdk_pixbuf_get_bits_per_sample(src), 
			     srcwidth,srcheight);
      if (!dest)
	return NULL;

      for (y = 0; y < srcheight; y++) 
	{ 
	  for (x = 0; x < srcwidth; x++) 
	    { 
	      p = gdk_pixbuf_get_pixels(src) + OFFSET (src, x, y); 
	      q = gdk_pixbuf_get_pixels(dest) + OFFSET (dest, srcwidth - x - 1, srcheight - y - 1); 
	      memcpy (q, p, gdk_pixbuf_get_n_channels(dest));
	    }
	} 
      break;
    case 270:
      dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace(src), 
			     gdk_pixbuf_get_has_alpha(src),
			     gdk_pixbuf_get_bits_per_sample(src), 
			     srcheight,srcwidth);
      if (!dest)
	return NULL;

      for (y = 0; y < srcheight; y++) 
	{ 
	  for (x = 0; x < srcwidth; x++) 
	    { 
	      p = gdk_pixbuf_get_pixels(src) + OFFSET (src, x, y); 
	      q = gdk_pixbuf_get_pixels(dest) + OFFSET (dest, srcheight - y - 1, x); 
	      memcpy (q, p, gdk_pixbuf_get_n_channels(dest));
	    }
	} 
      break;
    default:
      dest = NULL;
      g_warning ("gdk_pixbuf_rotate_simple() can only rotate "
		 "by multiples of 90 degrees");
      g_assert_not_reached ();
  } 

  return dest;
}
Esempio n. 18
0
void
testcase_exercise (Testcase* self)
{
	guchar   * gdkdata;
	guchar   * cairodata;
	gsize      index;
	GdkPixbuf* gdk_pixbuf;
	GdkPixbuf* cairo_pixbuf;
	cairo_t* cr;

	g_return_if_fail (IS_TESTCASE (self));

	g_signal_emit (self,
		       testcase_signals[EXERCISE_GDK],
		       0,
		       PRIV(self)->gdk_pixmap,
		       PRIV(self)->gdk_gc);

	cr = gdk_cairo_create (PRIV(self)->cairo_pixmap);
	g_signal_emit (self,
		       testcase_signals[EXERCISE_CAIRO],
		       0,
		       cr,
		       PRIV(self)->cairo_gc);
	cairo_destroy (cr);

	gdk_pixbuf   = gdk_pixbuf_get_from_drawable (NULL,
						     PRIV(self)->gdk_pixmap,
								 gdk_rgb_get_colormap (),
								 0, 0,
								 0, 0,
								 100, 80);
	cairo_pixbuf = gdk_pixbuf_get_from_drawable (NULL,
						     PRIV(self)->cairo_pixmap,
								 gdk_rgb_get_colormap (),
								 0, 0,
								 0, 0,
								 100, 80);

	gdkdata   = gdk_pixbuf_get_pixels (gdk_pixbuf);
	cairodata = gdk_pixbuf_get_pixels (cairo_pixbuf);

	g_return_if_fail (gdk_pixbuf_get_rowstride (gdk_pixbuf) == gdk_pixbuf_get_rowstride (cairo_pixbuf));
	g_return_if_fail (gdk_pixbuf_get_n_channels (gdk_pixbuf) == gdk_pixbuf_get_n_channels (cairo_pixbuf));
	g_return_if_fail (gdk_pixbuf_get_height (gdk_pixbuf) == gdk_pixbuf_get_height (cairo_pixbuf));
	g_return_if_fail (gdk_pixbuf_get_width (gdk_pixbuf) == gdk_pixbuf_get_width (cairo_pixbuf));

	PRIV(self)->passed = TRUE;

	for (index = 0; index < gdk_pixbuf_get_height (gdk_pixbuf) * gdk_pixbuf_get_rowstride (gdk_pixbuf); index++) {
		if (gdkdata[index] != cairodata[index]) {
			gchar* filepath;
			g_warning ("Eeek! Differences at byte %d: %c vs. %c",
				   index,
				   gdkdata[index],
				   cairodata[index]);
			PRIV(self)->passed = FALSE;

			filepath = g_strdup_printf ("%s-gdk.png",
						    g_get_prgname ());
			gdk_pixbuf_save (gdk_pixbuf,
					 filepath,
					 "png",
					 NULL, /* FIXME: handle errors */
					 NULL);
			g_message ("=> wrote gdk image to \"%s\"",
				   filepath);
			g_free (filepath);

			filepath = g_strdup_printf ("%s-cairo.png",
						    g_get_prgname ());
			gdk_pixbuf_save (cairo_pixbuf,
					 filepath,
					 "png",
					 NULL, /* FIXME: handle errors */
					 NULL);
			g_message ("=> wrote cairo image to \"%s\"",
				   filepath);
			g_free (filepath);
			break;
		}
	}

	g_object_unref (gdk_pixbuf);
	g_object_unref (cairo_pixbuf);
}
Esempio n. 19
0
void 
gp_image_set_diff_pixmap ( GpImage *image, GdkPixmap* pixmap, guint x_offset, guint y_offset )
{
	GdkPixbuf *pixbuf;
	GdkPixbuf *m_pixbuf;
	guchar *pixels, *m_pixels;
	guchar *p, *m_p;
	gint w, h;
	gint n_channels, rowstride;

	g_return_if_fail ( GP_IS_IMAGE (image) );
	

	pixbuf		=   image->priv->pixbuf;
	if(!gdk_pixbuf_get_has_alpha ( pixbuf ) )
	{  /*add alpha*/
		GdkPixbuf *tmp ;
		tmp = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
		g_object_unref(pixbuf);
		pixbuf = tmp;
	}
	m_pixbuf	=   gdk_pixbuf_copy ( pixbuf );
	
	w			=   gdk_pixbuf_get_width		( pixbuf );
	h			=   gdk_pixbuf_get_height		( pixbuf );

	gdk_pixbuf_get_from_drawable (  m_pixbuf, 
               						pixmap,
               						gdk_drawable_get_colormap (pixmap),
               						x_offset,y_offset,
               						0,0,
              						w,h);
	
	n_channels  =   gdk_pixbuf_get_n_channels   ( pixbuf );
	rowstride   =   gdk_pixbuf_get_rowstride	( pixbuf );
	pixels		=   gdk_pixbuf_get_pixels		( pixbuf );
	m_pixels	=   gdk_pixbuf_get_pixels		( m_pixbuf );
	while (h--) 
	{
		guint   i = w;
		p   = pixels;
		m_p = m_pixels;
		while (i--) 
		{
			pixel_union *pu, *m_pu;

			pu = (pixel_union *)p;
			m_pu = (pixel_union *)m_p;
				
			if(pu->ui32 == m_pu->ui32)
			{
				p[0] = 0; 
				p[1] = 0; 
				p[2] = 0; 
				p[3] = 0; 
			}
			p   += n_channels;
			m_p += n_channels;
		}
		pixels		+= rowstride;
		m_pixels	+= rowstride;
	}
	g_object_unref (m_pixbuf);

	
}
Esempio n. 20
0
int  hid_init(void)
{
    // Found a PC keyboard keymap
    match_keymap(tihw.calc_type);

    // Load kbd keymap
    if(keymap_load(options.keys_file) == -1)
    {
	    gchar *s = g_strdup_printf("unable to load this keymap: <%s>\n", options.keys_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

    // Found a skin
	match_skin(tihw.calc_type);

    // Load skin (2 parts)
    if(skin_load(&skin_infos, options.skin_file) == -1) 
    {
	    gchar *s = g_strdup_printf("unable to load this skin: <%s>\n", options.skin_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Allocate the skn pixbuf (if needed)
	skn = skin_infos.image;
  
	// Set skin keymap depending on calculator type
    switch(tihw.calc_type)
    {
    case TI92:
    case TI92p:
    case V200:
        skn_keymap = sknKey92;
        break;
    case TI89:
    case TI89t:
      	skn_keymap = sknKey89;
        break;
    default:
        {
	  	gchar *s = g_strdup_printf("no skin found for this calc\n");
	  	tiemu_error(0, s);
	  	g_free(s);
	  	return -1;
        }
	}

	// Set window/LCD sizes
	set_scale(options.view);
	set_infos();

    // Allocate the TI screen buffer
	lcd_bytmap = (uint32_t *)malloc(LCDMEM_W * LCDMEM_H);

    // Allocate the lcd pixbuf
    lcd = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, si.t * LCDMEM_W, si.t * LCDMEM_H);
    if(lcd == NULL)
    {
        gchar *s = g_strdup_printf("unable to create LCD pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Used by TI89 (the LCD view is clipped from memory view)
	si.l = gdk_pixbuf_new_subpixbuf(lcd, 0, 0, tihw.lcd_w, tihw.lcd_h);
    
	// Constants for LCD update (speed-up)
    li.n_channels = gdk_pixbuf_get_n_channels (lcd);
	li.width = gdk_pixbuf_get_width (lcd);
	li.height = gdk_pixbuf_get_height (lcd);
	li.rowstride = gdk_pixbuf_get_rowstride (lcd);
	li.pixels = gdk_pixbuf_get_pixels (lcd);

	// Create main window
	display_main_wnd();

    // Allocate the backing pixmap (used for drawing and refresh)
    pixmap = gdk_pixmap_new(main_wnd->window, wr.w, wr.h, -1);
    if(pixmap == NULL)
    {
        gchar *s = g_strdup_printf("unable to create backing pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }
    
    // Draw the skin and compute grayscale palette
	redraw_skin();
  	compute_grayscale();

    // Init the planar/chunky conversion table for LCD
  	compute_convtable();

    // Install LCD refresh: 100 FPS (10 ms)
    tid = g_timeout_add((params.lcd_rate == -1) ? 50 : params.lcd_rate, 
		(GtkFunction)hid_refresh, NULL);

	gtk_widget_show(main_wnd);	// show wnd here

	if(options.view == VIEW_FULL)
		gdk_window_fullscreen(main_wnd->window);
	
    return 0;
}
Esempio n. 21
0
/* This function is adapted from Gtk's gdk_cairo_set_source_pixbuf() you can
 * find in gdk/gdkcairo.c.
 * Copyright (C) Red Had, Inc.
 * LGPLv2+ */
static cairo_surface_t *
_cairo_new_surface_from_pixbuf (const GdkPixbuf *pixbuf)
{
  int              width         = gdk_pixbuf_get_width (pixbuf);
  int              height        = gdk_pixbuf_get_height (pixbuf);
  guchar          *gdk_pixels    = gdk_pixbuf_get_pixels (pixbuf);
  int              gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  int              n_channels    = gdk_pixbuf_get_n_channels (pixbuf);
  int              cairo_stride;
  guchar          *cairo_pixels;

  cairo_format_t   format;
  cairo_surface_t *surface;
  static const     cairo_user_data_key_t key;
  int              j;

  if (n_channels == 3)
    format = CAIRO_FORMAT_RGB24;
  else
    format = CAIRO_FORMAT_ARGB32;

  cairo_stride = cairo_format_stride_for_width (format, width);
  cairo_pixels = g_malloc (height * cairo_stride);
  surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels,
                                                 format,
                                                 width, height, cairo_stride);

  cairo_surface_set_user_data (surface, &key,
			       cairo_pixels, (cairo_destroy_func_t)g_free);

  for (j = height; j; j--)
    {
      guchar *p = gdk_pixels;
      guchar *q = cairo_pixels;

      if (n_channels == 3)
	      {
          guchar *end = p + 3 * width;

          while (p < end)
            {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
              q[0] = p[2];
              q[1] = p[1];
              q[2] = p[0];
#else
              q[1] = p[0];
              q[2] = p[1];
              q[3] = p[2];
#endif
              p += 3;
              q += 4;
            }
	      }
      else
        {
          guchar *end = p + 4 * width;
          guint t1,t2,t3;

#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END

          while (p < end)
            {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
              MULT(q[0], p[2], p[3], t1);
              MULT(q[1], p[1], p[3], t2);
              MULT(q[2], p[0], p[3], t3);
              q[3] = p[3];
#else
              q[0] = p[3];
              MULT(q[1], p[0], p[3], t1);
              MULT(q[2], p[1], p[3], t2);
              MULT(q[3], p[2], p[3], t3);
#endif

              p += 4;
              q += 4;
            }

#undef MULT
        }

      gdk_pixels += gdk_rowstride;
      cairo_pixels += cairo_stride;
    }
  return surface;
}
Esempio n. 22
0
static void
set_source_pixbuf(cairo_t         *cr,
		  const GdkPixbuf *pixbuf,
		  double           src_x,
		  double           src_y,
		  double           src_width,
		  double           src_height)
{
	gint width = gdk_pixbuf_get_width (pixbuf);
	gint height = gdk_pixbuf_get_height (pixbuf);
	guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
	int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
	int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
	int cairo_stride;
	guchar *cairo_pixels;
	cairo_format_t format;
	cairo_surface_t *surface;
	int j;

	if (n_channels == 3)
		format = CAIRO_FORMAT_RGB24;
	else
		format = CAIRO_FORMAT_ARGB32;

	surface = cairo_image_surface_create(format, width, height);
	if (cairo_surface_status(surface)) {
		cairo_set_source_surface(cr, surface, 0, 0);
		return;
	}

	cairo_stride = cairo_image_surface_get_stride(surface);
	cairo_pixels = cairo_image_surface_get_data(surface);

	for (j = height; j; j--) {
		guchar *p = gdk_pixels;
		guchar *q = cairo_pixels;

		if (n_channels == 3) {
			guchar *end = p + 3 * width;

			while (p < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
				q[0] = p[2];
				q[1] = p[1];
				q[2] = p[0];
#else
				q[1] = p[0];
				q[2] = p[1];
				q[3] = p[2];
#endif
				p += 3;
				q += 4;
			}
		} else {
			guchar *end = p + 4 * width;
			guint t1,t2,t3;

#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END

			while (p < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
				MULT(q[0], p[2], p[3], t1);
				MULT(q[1], p[1], p[3], t2);
				MULT(q[2], p[0], p[3], t3);
				q[3] = p[3];
#else
				q[0] = p[3];
				MULT(q[1], p[0], p[3], t1);
				MULT(q[2], p[1], p[3], t2);
				MULT(q[3], p[2], p[3], t3);
#endif

				p += 4;
				q += 4;
			}
#undef MULT
		}

		gdk_pixels += gdk_rowstride;
		cairo_pixels += cairo_stride;
	}
	cairo_surface_mark_dirty(surface);

	cairo_set_source_surface(cr, surface,
				 src_x + .5 * (src_width - width),
				 src_y + .5 * (src_height - height));
	cairo_surface_destroy(surface);
}
Esempio n. 23
0
void* iupdrvImageCreateImage(Ihandle *ih, const char* bgcolor, int make_inactive)
{
  GdkPixbuf* pixbuf;
  guchar *pixdata, *pixline_data;
  int rowstride, channels;
  unsigned char *imgdata, *line_data, bg_r=0, bg_g=0, bg_b=0;
  int x, y, i, bpp, colors_count = 0, has_alpha = 0;
  iupColor colors[256];

  bpp = iupAttribGetInt(ih, "BPP");

  if (bpp == 8)
    has_alpha = iupImageInitColorTable(ih, colors, &colors_count);
  else if (bpp == 32)
    has_alpha = 1;

  pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, ih->currentwidth, ih->currentheight);
  if (!pixbuf)
    return NULL;

  pixdata = gdk_pixbuf_get_pixels(pixbuf);
  rowstride = gdk_pixbuf_get_rowstride(pixbuf);
  channels = gdk_pixbuf_get_n_channels(pixbuf);
  imgdata = (unsigned char*)iupAttribGetStr(ih, "WID");

  if (make_inactive)  
    iupStrToRGB(bgcolor, &bg_r, &bg_g, &bg_b);

  if (bpp == 8)
  {
    if (make_inactive)
    {
      for (i=0;i<colors_count;i++)
      {
        if (colors[i].a == 0)
        {
          colors[i].r = bg_r;
          colors[i].g = bg_g;
          colors[i].b = bg_b;
          colors[i].a = 255;
        }

        iupImageColorMakeInactive(&(colors[i].r), &(colors[i].g), &(colors[i].b), 
                                  bg_r, bg_g, bg_b);
      }
    }

    for (y=0; y<ih->currentheight; y++)
    {
      pixline_data = pixdata + y * rowstride;
      line_data = imgdata + y * ih->currentwidth;

      for (x=0; x<ih->currentwidth; x++)
      {
        unsigned char index = line_data[x];
        iupColor* c = &colors[index];
        guchar *r = &pixline_data[channels*x],
               *g = r+1,
               *b = g+1,
               *a = b+1;

        *r = c->r;
        *g = c->g;
        *b = c->b;

        if (has_alpha)
          *a = c->a;
      }
    }
  }
  else /* bpp == 32 or bpp == 24 */
  {
    for (y=0; y<ih->currentheight; y++)
    {
      pixline_data = pixdata + y * rowstride;
      line_data = imgdata + y * ih->currentwidth*channels;

      memcpy(pixline_data, line_data, ih->currentwidth*channels);

      if (make_inactive)
      {
        for (x=0; x<ih->currentwidth; x++)
        {
          guchar *r = &pixline_data[channels*x],
                 *g = r+1,
                 *b = g+1,
                 *a = b+1;

          if (has_alpha)
          {
            if (*a != 255)
            {
              *r = iupALPHABLEND(*r, bg_r, *a);
              *g = iupALPHABLEND(*g, bg_g, *a);
              *b = iupALPHABLEND(*b, bg_b, *a);
            }
            else
              *a = 255;
          }

          iupImageColorMakeInactive(r, g, b, 
                                    bg_r, bg_g, bg_b);
        }
      }
    }
  }

  return pixbuf;
}
Esempio n. 24
0
gboolean
_cogl_bitmap_from_file (CoglBitmap   *bmp,
			const gchar  *filename,
			GError      **error)
{
  GdkPixbuf        *pixbuf;
  gboolean          has_alpha;
  GdkColorspace     color_space;
  CoglPixelFormat   pixel_format;
  gint              width;
  gint              height;
  gint              rowstride;
  gint              bits_per_sample;
  gint              n_channels;
  gint              last_row_size;
  guchar           *pixels;
  guchar           *out_data;
  guchar           *out;
  gint              r;

  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (bmp == NULL)
    return FALSE;

  /* Load from file using GdkPixbuf */
  pixbuf = gdk_pixbuf_new_from_file (filename, error);
  if (pixbuf == NULL)
    return FALSE;

  /* Get pixbuf properties */
  has_alpha       = gdk_pixbuf_get_has_alpha (pixbuf);
  color_space     = gdk_pixbuf_get_colorspace (pixbuf);
  width           = gdk_pixbuf_get_width (pixbuf);
  height          = gdk_pixbuf_get_height (pixbuf);
  rowstride       = gdk_pixbuf_get_rowstride (pixbuf);
  bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
  n_channels      = gdk_pixbuf_get_n_channels (pixbuf);

  /* The docs say this is the right way */
  last_row_size = width * ((n_channels * bits_per_sample + 7) / 8);

  /* According to current docs this should be true and so
   * the translation to cogl pixel format below valid */
  g_assert (bits_per_sample == 8);

  if (has_alpha)
    g_assert (n_channels == 4);
  else
    g_assert (n_channels == 3);

  /* Translate to cogl pixel format */
  switch (color_space)
    {
    case GDK_COLORSPACE_RGB:
      /* The only format supported by GdkPixbuf so far */
      pixel_format = has_alpha ?
	COGL_PIXEL_FORMAT_RGBA_8888 :
	COGL_PIXEL_FORMAT_RGB_888;
      break;

    default:
      /* Ouch, spec changed! */
      g_object_unref (pixbuf);
      return FALSE;
    }

  /* FIXME: Any way to destroy pixbuf but retain pixel data? */

  pixels   = gdk_pixbuf_get_pixels (pixbuf);
  out_data = (guchar*) g_malloc (height * rowstride);
  out      = out_data;

  /* Copy up to last row */
  for (r = 0; r < height-1; ++r)
    {
      memcpy (out, pixels, rowstride);
      pixels += rowstride;
      out += rowstride;
    }

  /* Copy last row */
  memcpy (out, pixels, last_row_size);

  /* Destroy GdkPixbuf object */
  g_object_unref (pixbuf);

  /* Store bitmap info */
  bmp->data = out_data; /* The stored data the same alignment constraints as a
                         * gdkpixbuf but stores a full rowstride in the last
                         * scanline
                         */
  bmp->format = pixel_format;
  bmp->width = width;
  bmp->height = height;
  bmp->rowstride = rowstride;

  return TRUE;
}
Esempio n. 25
0
File: print.c Progetto: gdt/viking
static void draw_page_cairo(GtkPrintContext *context, PrintData *data)
{
  cairo_t         *cr;
  GdkPixbuf       *pixbuf_to_draw; 
  cairo_surface_t *surface;
  guchar          *surface_pixels;
  guchar          *pixbuf_pixels;
  gint             stride;
  gint             pixbuf_stride;
  gint             pixbuf_n_channels;
  gdouble          cr_dpi_x;
  gdouble          cr_dpi_y;
  gdouble          scale_x;
  gdouble          scale_y;
  gint             y;

  cr = gtk_print_context_get_cairo_context(context);
  pixbuf_to_draw = gdk_pixbuf_get_from_drawable(NULL,
                               GDK_DRAWABLE(vik_viewport_get_pixmap(data->vvp)),
                               NULL, 0, 0, 0, 0, data->width, data->height);
  surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                       data->width, data->height);
  
  cr_dpi_x  = gtk_print_context_get_dpi_x  (context);
  cr_dpi_y  = gtk_print_context_get_dpi_y  (context);

  scale_x = cr_dpi_x / data->xres;
  scale_y = cr_dpi_y / data->yres;

  cairo_translate (cr,
                   data->offset_x / cr_dpi_x * 72.0,
                   data->offset_y / cr_dpi_y * 72.0);
  cairo_scale (cr, scale_x, scale_y);

  surface_pixels = cairo_image_surface_get_data (surface);
  stride = cairo_image_surface_get_stride (surface);
  pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf_to_draw);
  pixbuf_stride = gdk_pixbuf_get_rowstride(pixbuf_to_draw);
  pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf_to_draw);

  // fprintf(stderr, "DEBUG: %s() surface_pixels=%p pixbuf_pixels=%p size=%d surface_width=%d surface_height=%d stride=%d data_height=%d pixmap_stride=%d pixmap_nchannels=%d pixmap_bit_per_Sample=%d\n", __PRETTY_FUNCTION__, surface_pixels, pixbuf_pixels, stride * data->height, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), stride, data->height, gdk_pixbuf_get_rowstride(pixbuf_to_draw), gdk_pixbuf_get_n_channels(pixbuf_to_draw), gdk_pixbuf_get_bits_per_sample(pixbuf_to_draw));

  /* Assume the pixbuf has 8 bits per channel */
  for (y = 0; y < data->height; y++, surface_pixels += stride, pixbuf_pixels += pixbuf_stride) {
    switch (pixbuf_n_channels) {
      case 3:
        copy_row_from_rgb (surface_pixels, pixbuf_pixels, data->width);
        break;
      case 4:
        copy_row_from_rgba (surface_pixels, pixbuf_pixels, data->width);
        break;
    }
  }

  g_object_unref(G_OBJECT(pixbuf_to_draw));

  cairo_set_source_surface(cr, surface, 0, 0);
  cairo_rectangle(cr, 0, 0, data->width, data->height);
  cairo_fill(cr);
  cairo_surface_destroy(surface);
}
static void
render (ChamplainRenderer *renderer, ChamplainTile *tile)
{
  ChamplainImageRendererPrivate *priv = GET_PRIVATE (renderer);
  gboolean error = TRUE;
  GdkPixbufLoader *loader = NULL;
  GError *gerror = NULL;
  ClutterActor *actor = NULL;
  GdkPixbuf *pixbuf;

  if (!priv->data || priv->size == 0)
    goto finish;

  loader = gdk_pixbuf_loader_new ();
  if (!gdk_pixbuf_loader_write (loader,
          (const guchar *) priv->data,
          priv->size,
          &gerror))
    {
      if (gerror)
        {
          g_warning ("Unable to load the pixbuf: %s", gerror->message);
          g_error_free (gerror);
        }
      goto finish;
    }

  gdk_pixbuf_loader_close (loader, &gerror);
  if (gerror)
    {
      g_warning ("Unable to close the pixbuf loader: %s", gerror->message);
      g_error_free (gerror);
      goto finish;
    }

  /* Load the image into clutter */
  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
  actor = clutter_texture_new ();
  if (!clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (actor),
          gdk_pixbuf_get_pixels (pixbuf),
          gdk_pixbuf_get_has_alpha (pixbuf),
          gdk_pixbuf_get_width (pixbuf),
          gdk_pixbuf_get_height (pixbuf),
          gdk_pixbuf_get_rowstride (pixbuf),
          gdk_pixbuf_get_bits_per_sample (pixbuf) *
          gdk_pixbuf_get_n_channels (pixbuf) / 8,
          0, &gerror))
    {
      if (gerror)
        {
          g_warning ("Unable to transfer to clutter: %s", gerror->message);
          g_error_free (gerror);
        }

      g_object_unref (actor);
      actor = NULL;
      goto finish;
    }

  error = FALSE;

finish:

  if (actor)
    champlain_tile_set_content (tile, actor);

  g_signal_emit_by_name (tile, "render-complete", priv->data, priv->size, error);

  if (loader)
    g_object_unref (loader);
}
Esempio n. 27
0
static nsresult
moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
                          nsIChannel** aChannel)
{
  int width = gdk_pixbuf_get_width(aPixbuf);
  int height = gdk_pixbuf_get_height(aPixbuf);
  NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
                 gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB &&
                 gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 &&
                 gdk_pixbuf_get_has_alpha(aPixbuf) &&
                 gdk_pixbuf_get_n_channels(aPixbuf) == 4,
                 NS_ERROR_UNEXPECTED);

  const int n_channels = 4;
  gsize buf_size = 2 + n_channels * height * width;
  uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size);
  NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
  uint8_t* out = buf;

  *(out++) = width;
  *(out++) = height;

  const guchar* const pixels = gdk_pixbuf_get_pixels(aPixbuf);
  int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels;

  // encode the RGB data and the A data
  const guchar* in = pixels;
  for (int y = 0; y < height; ++y, in += rowextra) {
    for (int x = 0; x < width; ++x) {
      uint8_t r = *(in++);
      uint8_t g = *(in++);
      uint8_t b = *(in++);
      uint8_t a = *(in++);
#define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
#if MOZ_LITTLE_ENDIAN
      *(out++) = DO_PREMULTIPLY(b);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = a;
#else
      *(out++) = a;
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(b);
#endif
#undef DO_PREMULTIPLY
    }
  }

  NS_ASSERTION(out == buf + buf_size, "size miscalculation");

  nsresult rv;
  nsCOMPtr<nsIStringInputStream> stream =
    do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);

  // Prevent the leaking of buf
  if (NS_WARN_IF(NS_FAILED(rv))) {
    free(buf);
    return rv;
  }

  // stream takes ownership of buf and will free it on destruction.
  // This function cannot fail.
  rv = stream->AdoptData((char*)buf, buf_size);

  // If this no longer holds then re-examine buf's lifetime.
  MOZ_ASSERT(NS_SUCCEEDED(rv));
  NS_ENSURE_SUCCESS(rv, rv);

  // nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
  // this iconChannel. Use the most restrictive security settings for the
  // temporary loadInfo to make sure the channel can not be openend.
  nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
  return NS_NewInputStreamChannel(aChannel,
                                  aURI,
                                  stream,
                                  nullPrincipal,
                                  nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
                                  nsIContentPolicy::TYPE_INTERNAL_IMAGE,
                                  NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}
Esempio n. 28
0
/* Set_property handler for the pixbuf canvas item */
static void
foo_canvas_pixbuf_set_property (GObject            *object,
				guint               param_id,
				const GValue       *value,
				GParamSpec         *pspec)
{
	FooCanvasItem *item;
	FooCanvasPixbuf *gcp;
	PixbufPrivate *priv;
	GdkPixbuf *pixbuf;
	double val;

	g_return_if_fail (object != NULL);
	g_return_if_fail (FOO_IS_CANVAS_PIXBUF (object));

	item = FOO_CANVAS_ITEM (object);
	gcp = FOO_CANVAS_PIXBUF (object);
	priv = gcp->priv;

	switch (param_id) {
	case PROP_PIXBUF:
		if (g_value_get_object (value))
			pixbuf = GDK_PIXBUF (g_value_get_object (value));
		else
			pixbuf = NULL;
		if (pixbuf != priv->pixbuf) {
			if (pixbuf) {
				g_return_if_fail
				    (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
				g_return_if_fail
				    (gdk_pixbuf_get_n_channels (pixbuf) == 3
				     || gdk_pixbuf_get_n_channels (pixbuf) == 4);
				g_return_if_fail
				    (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);

				g_object_ref (pixbuf);
			}

			if (priv->pixbuf)
				g_object_unref (priv->pixbuf);
			priv->pixbuf = pixbuf;

			if (priv->pixbuf_scaled) {
				g_object_unref (priv->pixbuf_scaled);
				priv->pixbuf_scaled = NULL;
			}
		}

		priv->need_pixbuf_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_WIDTH:
		val = g_value_get_double (value);
		g_return_if_fail (val >= 0.0);
		priv->width = val;
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_WIDTH_SET:
		priv->width_set = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_WIDTH_IN_PIXELS:
		priv->width_in_pixels = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_HEIGHT:
		val = g_value_get_double (value);
		g_return_if_fail (val >= 0.0);
		priv->height = val;
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_HEIGHT_SET:
		priv->height_set = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_HEIGHT_IN_PIXELS:
		priv->height_in_pixels = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_X:
		priv->x = g_value_get_double (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_X_IN_PIXELS:
		priv->x_in_pixels = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_Y:
		priv->y = g_value_get_double (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_Y_IN_PIXELS:
		priv->y_in_pixels = g_value_get_boolean (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_ANCHOR:
		priv->anchor = g_value_get_enum (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_INTERP_TYPE:
		priv->interp_type = g_value_get_enum (value);
		priv->need_xform_update = TRUE;
		foo_canvas_item_request_update (item);
		break;

	case PROP_POINT_IGNORES_ALPHA:
		priv->point_ignores_alpha = g_value_get_boolean (value);
		break;

	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
		break;
	}
}
Esempio n. 29
0
static void
image_set_from_surface (GtkImage        *gtkimage,
			cairo_surface_t *surface)
{
	GdkPixbuf       *pixbuf;
	cairo_surface_t *image;
	cairo_t         *cr;
	gboolean         has_alpha;
	gint             width, height;
	cairo_format_t   surface_format;
	gint             pixbuf_n_channels;
	gint             pixbuf_rowstride;
	guchar          *pixbuf_pixels;
	gint             x, y;

	width = cairo_image_surface_get_width (surface);
	height = cairo_image_surface_get_height (surface);
	
	surface_format = cairo_image_surface_get_format (surface);
	has_alpha = (surface_format == CAIRO_FORMAT_ARGB32);

	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
				 TRUE, 8,
				 width, height);
	pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
	pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
	pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf);

	image = cairo_image_surface_create_for_data (pixbuf_pixels,
						     surface_format,
						     width, height,
						     pixbuf_rowstride);
	cr = cairo_create (image);
	cairo_set_source_surface (cr, surface, 0, 0);

	if (has_alpha)
		cairo_mask_surface (cr, surface, 0, 0);
	else
		cairo_paint (cr);

	cairo_destroy (cr);
	cairo_surface_destroy (image);

	for (y = 0; y < height; y++) {
		guchar *p = pixbuf_pixels + y * pixbuf_rowstride;

		for (x = 0; x < width; x++) {
			guchar tmp;
			
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
			tmp = p[0];
			p[0] = p[2];
			p[2] = tmp;
			p[3] = (has_alpha) ? p[3] : 0xff;
#else
			tmp = p[0];
			p[0] = (has_alpha) ? p[3] : 0xff;
			p[3] = p[2];
			p[2] = p[1];
			p[1] = tmp;
#endif			
			p += pixbuf_n_channels;
		}
	}

	gtk_image_set_from_pixbuf (gtkimage, pixbuf);
	g_object_unref (pixbuf);
}
void
gdk_pixbuf_blend (
	GdkPixbuf* dst,
	const lib::rect dst_rc,
	GdkPixbuf* src,
	const lib::rect src_rc,
	double opacity_in,
	double opacity_out,
	const lib::color_t chroma_low,
	const lib::color_t chroma_high,
	const lib::color_t mask_color)
{
  //TBD: dst(L,T,W,H) != src(L,T,W,H), alpha channel in dst/src
	assert(dst != NULL && src != NULL);
	guint	n_channels_dst = gdk_pixbuf_get_n_channels (dst);
	guint	n_channels_src = gdk_pixbuf_get_n_channels (src);
	assert (n_channels_dst >= 3 && n_channels_dst <= 4);
//	assert (n_channels_dst == n_channels_src);

	gint	dst_L = dst_rc.x, dst_T = dst_rc.y;
	guint	dst_W = dst_rc.w, dst_H = dst_rc.h;
	gint	src_L = src_rc.x, src_T = src_rc.y;
	guint	src_W = src_rc.w, src_H = src_rc.h;
	guchar* dst_col, * dst_row, * src_col, * src_row;
	gint	col, row;
	gint	L = dst_L <= src_L ? dst_L : src_L;
	gint	T = dst_T <= src_T ? dst_T : src_T;
	guint	W = dst_W <= src_W ? dst_W : src_W;
	guint	H = dst_H <= src_H ? dst_H : src_H;
	guint	R = L + W;
	guint	B = T + H;

	guint weight_in = static_cast<guint>(round(opacity_in*255.0));
	guint weight_out = static_cast<guint>(round(opacity_out*255.0));

	guchar r_l = redc(chroma_low), r_h = redc(chroma_high), r_m = redc(mask_color);
	guchar g_l = greenc(chroma_low), g_h = greenc(chroma_high), g_m = greenc(mask_color);
	guchar b_l = bluec(chroma_low), b_h = bluec(chroma_high), b_m = bluec(mask_color);
	AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:r_l=%3d,g_l=%3d,b_l=%3d,w_in=%d,w_out=%d", r_l,g_l,b_l,weight_in, weight_out);
AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:r_h=%3d,g_h=%3d,b_h=%3d", r_h,g_h,b_h);

	dst_row = gdk_pixbuf_get_pixels (dst);
	src_row = gdk_pixbuf_get_pixels (src);

	for (row = T; row < B; row++) {
		dst_col = dst_row;
		src_col = src_row;
		for (col = L; col < R; col++) {
			guchar r = src_col[0];
			guchar g = src_col[1];
			guchar b = src_col[2];
			if ( ! (mask_color
				&& r == r_m && g == g_m && b == b_m)) {
				guchar a = n_channels_src == 4 ? src_row[3] : 0xff;
//AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:rc=(%3d,%3d),dst=(%3d,%3d,%3d),src=(%3d,%3d,%3d)",row,col,dst_col[0],dst_col[1],dst_col[2],r,g,b);
			// chromakeying
				if ( // check all components in chromakey range
					r_l <= r && r <= r_h
					&&	g_l <= g && g <= g_h
					&&	b_l <= b && b <= b_h
				) {
					// blend the pixel from 'src' into 'dst'
					dst_col[0] = _blend_pixel(dst_col[0], r, weight_in);
					dst_col[1] = _blend_pixel(dst_col[1], g, weight_in);
					dst_col[2] = _blend_pixel(dst_col[2], b, weight_in);
					if (n_channels_dst == 4)
						dst_col[3] = _blend_pixel(dst_col[3], a, weight_in);
				} else {
					// blend the pixel from 'src' into 'dst'
					dst_col[0] = _blend_pixel(dst_col[0], r, weight_out);
					dst_col[1] = _blend_pixel(dst_col[1], g, weight_out);
					dst_col[2] = _blend_pixel(dst_col[2], b, weight_out);
					if (n_channels_dst == 4)
						dst_col[3] = _blend_pixel(dst_col[3], a, weight_out);
				}
			}
			dst_col += n_channels_dst;
			src_col += n_channels_src;
		}
		dst_row += gdk_pixbuf_get_rowstride(dst);
		src_row += gdk_pixbuf_get_rowstride(src);
	}

}