void art_draw_rgb_image(art_buffer_p dest_buffer, int dest_x, int dest_y, int dest_width, int dest_height, unsigned char *src_buffer, int src_width, int src_height) { double affine[6]; affine[0] = dest_width / (float)src_width; affine[1] = 0; affine[2] = 0; affine[3] = dest_height / (float)src_height; affine[4] = dest_x; affine[5] = dest_buffer->height - dest_y - dest_height; art_rgb_affine(dest_buffer->buffer, 0, 0, dest_buffer->width, dest_buffer->height, dest_buffer->width * 3, (art_u8 *)src_buffer, src_width, src_height, src_width * 3, affine, ART_FILTER_NEAREST, NULL); }
void art_draw_transformed_rgb_image(art_buffer_p dest_buffer, unsigned char *src_buffer, int src_width, int src_height, int dest_x, int dest_y, float angle, float scale) { double affine[6]; affine[0] = scale * cos(angle); affine[1] = -scale * sin(angle); affine[2] = scale * sin(angle); affine[3] = scale * cos(angle); affine[4] = dest_x - src_height * scale * sin(angle); affine[5] = dest_buffer->height - dest_y - src_height * scale * cos(angle); art_rgb_affine(dest_buffer->buffer, 0, 0, dest_buffer->width, dest_buffer->height, dest_buffer->width * 3, (art_u8 *)src_buffer, src_width, src_height, src_width * 3, affine, ART_FILTER_NEAREST, NULL); }
/** * art_rgb_pixbuf_affine: Affine transform source RGB pixbuf and composite. * @dst: Destination image RGB buffer. * @x0: Left coordinate of destination rectangle. * @y0: Top coordinate of destination rectangle. * @x1: Right coordinate of destination rectangle. * @y1: Bottom coordinate of destination rectangle. * @dst_rowstride: Rowstride of @dst buffer. * @pixbuf: source image pixbuf. * @affine: Affine transform. * @level: Filter level. * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing. * * Affine transform the source image stored in @src, compositing over * the area of destination image @dst specified by the rectangle * (@x0, @y0) - (@x1, @y1). As usual in libart, the left and top edges * of this rectangle are included, and the right and bottom edges are * excluded. * * The @alphagamma parameter specifies that the alpha compositing be * done in a gamma-corrected color space. In the current * implementation, it is ignored. * * The @level parameter specifies the speed/quality tradeoff of the * image interpolation. Currently, only ART_FILTER_NEAREST is * implemented. **/ void art_rgb_pixbuf_affine (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride, const ArtPixBuf *pixbuf, const double affine[6], ArtFilterLevel level, ArtAlphaGamma *alphagamma) { if (pixbuf->format != ART_PIX_RGB) { art_warn ("art_rgb_pixbuf_affine: need RGB format image\n"); return; } if (pixbuf->bits_per_sample != 8) { art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n"); return; } if (pixbuf->n_channels != 3 + (pixbuf->has_alpha != 0)) { art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n"); return; } if (pixbuf->has_alpha) art_rgb_rgba_affine (dst, x0, y0, x1, y1, dst_rowstride, pixbuf->pixels, pixbuf->width, pixbuf->height, pixbuf->rowstride, affine, level, alphagamma); else art_rgb_affine (dst, x0, y0, x1, y1, dst_rowstride, pixbuf->pixels, pixbuf->width, pixbuf->height, pixbuf->rowstride, affine, level, alphagamma); }
static void make_testpat (void) { ArtVpath *vpath, *vpath2, *vpath3; ArtSVP *svp, *svp2; ArtSVP *svp3; art_u8 buf[512 * 512 * BYTES_PP]; int i, j; int iter; art_u8 colorimg[256][256][3]; art_u8 rgbaimg[256][256][4]; art_u8 bitimg[16][2]; int x, y; double affine[6]; double affine2[6]; double affine3[6]; ArtAlphaGamma *alphagamma; double dash_data[] = { 20 }; ArtVpathDash dash; dash.offset = 0; dash.n_dash = 1; dash.dash = dash_data; #ifdef TEST_AFFINE test_affine (); exit (0); #endif vpath = randstar (50); svp = art_svp_from_vpath (vpath); art_free (vpath); vpath2 = randstar (50); #if 1 vpath3 = art_vpath_dash (vpath2, &dash); art_free (vpath2); svp2 = art_svp_vpath_stroke (vpath3, ART_PATH_STROKE_JOIN_MITER, ART_PATH_STROKE_CAP_BUTT, 15, 4, 0.5); art_free (vpath3); #else svp2 = art_svp_from_vpath (vpath2); #endif #if 1 svp3 = art_svp_intersect (svp, svp2); #else svp3 = svp2; #endif #if 0 print_svp (svp); #endif for (y = 0; y < 256; y++) for (x = 0; x < 256; x++) { colorimg[y][x][0] = (x + y) >> 1; colorimg[y][x][1] = (x + (255 - y)) >> 1; colorimg[y][x][2] = ((255 - x) + y) >> 1; rgbaimg[y][x][0] = (x + y) >> 1; rgbaimg[y][x][1] = (x + (255 - y)) >> 1; rgbaimg[y][x][2] = ((255 - x) + y) >> 1; rgbaimg[y][x][3] = y; } for (y = 0; y < 16; y++) for (x = 0; x < 2; x++) bitimg[y][x] = (x << 4) | y; affine[0] = 0.5; affine[1] = .2; affine[2] = -.2; affine[3] = 0.5; affine[4] = 64; affine[5] = 64; affine2[0] = 1; affine2[1] = -.2; affine2[2] = .2; affine2[3] = 1; affine2[4] = 128; affine2[5] = 128; affine3[0] = 5; affine3[1] = -.2; affine3[2] = .2; affine3[3] = 5; affine3[4] = 384; affine3[5] = 32; #if 0 alphagamma = art_alphagamma_new (1.8); #else alphagamma = NULL; #endif #ifdef COLOR printf ("P6\n512 512\n255\n"); #else printf ("P5\n512 512\n255\n"); #endif for (iter = 0; iter < NUM_ITERS; iter++) for (j = 0; j < 512; j += TILE_SIZE) for (i = 0; i < 512; i += TILE_SIZE) { #ifdef COLOR art_rgb_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE, 0xffe0a0, 0x100040, buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP, alphagamma); art_rgb_svp_alpha (svp2, i, j, i + TILE_SIZE, j + TILE_SIZE, 0xff000080, buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP, alphagamma); art_rgb_svp_alpha (svp3, i, j, i + TILE_SIZE, j + TILE_SIZE, 0x00ff0080, buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP, alphagamma); art_rgb_affine (buf + (j * 512 + i) * BYTES_PP, i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP, (art_u8 *)colorimg, 256, 256, 256 * 3, affine, ART_FILTER_NEAREST, alphagamma); art_rgb_rgba_affine (buf + (j * 512 + i) * BYTES_PP, i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP, (art_u8 *)rgbaimg, 256, 256, 256 * 4, affine2, ART_FILTER_NEAREST, alphagamma); art_rgb_bitmap_affine (buf + (j * 512 + i) * BYTES_PP, i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP, (art_u8 *)bitimg, 16, 16, 2, 0xffff00ff, affine3, ART_FILTER_NEAREST, alphagamma); #else art_gray_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE, buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP); #endif } art_svp_free (svp2); art_svp_free (svp3); art_svp_free (svp); #if 1 fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout); #endif }
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImagePainter_drawPixels (JNIEnv *env, jobject obj __attribute__((unused)), jobject gc_obj, jint bg_red, jint bg_green, jint bg_blue, jint x, jint y, jint width, jint height, jintArray jpixels, jint offset, jint scansize, jdoubleArray jaffine) { struct graphics *g; jint *pixels, *elems; guchar *packed; int i; jsize num_pixels; guchar *j_rgba, *c_rgb; g = (struct graphics *) NSA_GET_PTR (env, gc_obj); if (!jpixels) return; elems = (*env)->GetIntArrayElements (env, jpixels, NULL); num_pixels = (*env)->GetArrayLength (env, jpixels); /* get a copy of the pixel data so we can modify it */ pixels = malloc (sizeof (jint) * num_pixels); memcpy (pixels, elems, sizeof (jint) * num_pixels); (*env)->ReleaseIntArrayElements (env, jpixels, elems, 0); #ifndef WORDS_BIGENDIAN /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */ for (i = 0; i < num_pixels; i++) pixels[i] = SWAPU32 ((unsigned)pixels[i]); #endif packed = (guchar *) malloc (sizeof (guchar) * 3 * num_pixels); j_rgba = (guchar *) pixels; c_rgb = packed; /* copy over pixels in DirectColorModel format to 24 bit RGB image data, and process the alpha channel */ for (i = 0; i < num_pixels; i++) { jint ialpha = *j_rgba++; switch (ialpha) { case 0: /* full transparency */ *c_rgb++ = bg_red; *c_rgb++ = bg_green; *c_rgb++ = bg_blue; j_rgba += 3; break; case 255: /* opaque */ *c_rgb++ = *j_rgba++; *c_rgb++ = *j_rgba++; *c_rgb++ = *j_rgba++; break; default: /* compositing required */ { jfloat alpha = ialpha / 255.0; jfloat comp_alpha = 1.0 - alpha; *c_rgb++ = *j_rgba++ * alpha + bg_red * comp_alpha; *c_rgb++ = *j_rgba++ * alpha + bg_green * comp_alpha; *c_rgb++ = *j_rgba++ * alpha + bg_blue * comp_alpha; } break; } } if (jaffine) { jdouble *affine; ArtAlphaGamma *alphagamma = NULL; art_u8 *dst; int new_width, new_height; affine = (*env)->GetDoubleArrayElements (env, jaffine, NULL); new_width = abs (width * affine[0]); new_height = abs (height * affine[3]); dst = (art_u8 *) malloc (sizeof (art_u8) * 3 * (new_width * new_height)); art_rgb_affine (dst, 0, 0, new_width, new_height, new_width * 3, (art_u8 *) packed + offset * 3, width, height, scansize * 3, affine, ART_FILTER_NEAREST, alphagamma); (*env)->ReleaseDoubleArrayElements (env, jaffine, affine, JNI_ABORT); free (packed); packed = (guchar *) dst; width = scansize = new_width; height = new_height; offset = 0; } gdk_threads_enter (); if (!g || !GDK_IS_DRAWABLE (g->drawable)) { gdk_threads_leave (); return; } gdk_draw_rgb_image (g->drawable, g->gc, x + g->x_offset, y + g->y_offset, width, height, GDK_RGB_DITHER_NORMAL, packed + offset * 3, scansize * 3); gdk_threads_leave (); free (pixels); free (packed); }