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; }
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; } }
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); }
/** * 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; }
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; }
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; }
/* 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; }
/*! 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); };
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; }
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(); }
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; } }
/** * 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); } }
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; }
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); } }
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; }
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); }
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); }
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; }
/* 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; }
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); }
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; }
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; }
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); }
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)); }
/* 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; } }
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); } }