?? img.cc
字號:
/* * img.c - * * Copyright (c) 1998 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include <stdio.h>#include <qimage.h>#include "toolkit.h"/* interfaces of image conversion functions *///Image* readGifFile ( int fd , char *fn);//Image* readGifData ( unsigned char*, long len );//Image* readJpegFile ( int fd );//Image* readJpegData ( unsigned char*, long len );//Image* readPngFile ( int fd );//Image* readPngData ( unsigned char*, long len );/************************************************************************************ * own auxiliary funcs */Image*createImage ( int width, int height ){ Image * img = (Image*)AWT_CALLOC( 1, sizeof( Image)); img->trans = -1; /* default to no alpha */ img->width = width; /* we need to (temp) store them for subsequent X image creation */ img->height = height; return img;}#if 0static intcreateShmXImage ( Toolkit* X, Image* img, int depth, int isMask ){ return 0;}static voiddestroyShmXImage ( Toolkit* X, Image* img, int isMask ){}#endifvoidcreateXImage ( Toolkit* X, Image* img ){ int bitmap_pad; int bytes_per_line; int bytes_per_pix; unsigned int nPix; char *data;#if 0 Visual *vis = DefaultVisual( X->dsp, DefaultScreen( X->dsp)); int depth = DefaultDepth( X->dsp, DefaultScreen( X->dsp)); if ( depth <= 8) bytes_per_pix = 1; else if ( depth <= 16) bytes_per_pix = 2; else bytes_per_pix = 4; bytes_per_line = bytes_per_pix * img->width; bitmap_pad = bytes_per_pix * 8; nPix = img->width * img->height; if ( (X->shm == USE_SHM) && (nPix > X->shmThreshold) && (img->alpha == 0) ) { if ( createShmXImage( X, img, depth, False) ){ DBG( AWT_IMG, printf("alloc Shm: %p %p %p (%dx%d) \n", img, img->qImg, img->shmiImg, img->width, img->height)); return; } } data = AWT_CALLOC( nPix, bytes_per_pix); img->xImg = XCreateImage( X->dsp, vis, depth, ZPixmap, 0, data, img->width, img->height, bitmap_pad, bytes_per_line);#endif img->qImg = new QImage(); DBG( AWT_IMG, printf( "alloc: %p %p (%dx%d)\n", img, img->qImg, img->width, img->height));}voidcreateXMaskImage ( Toolkit* X, Image* img ){ int bytes_per_line; unsigned int nBytes, nPix; char *data; //Visual *vis = DefaultVisual( X->dsp, DefaultScreen( X->dsp)); bytes_per_line = (img->width + 7) / 8; nPix = img->width * img->height; nBytes = bytes_per_line * img->height;#if 0 if ( (X->shm == USE_SHM) && (nPix > X->shmThreshold) ) { if ( createShmXImage( X, img, 1, True) ){ DBG( AWT_IMG, printf( "alloc Shm mask: %p %p %p (%dx%d) \n", img, img->xMask, img->shmiMask, img->width, img->height)); return; } }#endif data = (char*)AWT_MALLOC( nBytes); memset( data, 0xff, nBytes); img->qImg_AlphaMask = new QImage();// img->xMask = XCreateImage( X->dsp, vis, 1, XYBitmap, 0,// data, img->width, img->height, 8, bytes_per_line ); DBG( AWT_IMG, printf( "alloc mask: %p %p (%dx%d)\n", img, img->qImg_AlphaMask, img->width, img->height));}voidcreateAlphaImage ( Toolkit* X, Image *img ){ int nBytes = img->width * img->height; img->alpha = (AlphaImage*)AWT_MALLOC( sizeof( AlphaImage)); img->alpha->width = img->width; img->alpha->height = img->height; img->alpha->buf = (unsigned char*)AWT_MALLOC( nBytes); memset( img->alpha->buf, 0xff, nBytes);}/* * For images with a full alpha channel, check if we really need an alpha byte for * each pel, or if a mask bitmap (alpha 0x00 / 0xff) will be sufficient */intneedsFullAlpha ( Toolkit* X, Image *img, double threshold ){ int i, j, a; int n = 0, max; if ( !img->alpha ) return 0; max = (img->width * img->height) * threshold; for ( i=0; i<img->height; i++ ) { for ( j=0; j<img->width; j++ ) { a = GetAlpha( img->alpha, j, i); if ( (a != 0) && (a != 0xff) ) { if ( ++n > max ) return 1; } } } return 0;}/* * A full alpha image channel is way slower than using a mask bitmap (= 0 / 0xff alpha). * This function provides a simple alpha-to-mask translation *//* also used in imgpng */voidreduceAlpha ( Toolkit* X, Image* img, int threshold ){ int i, j, a; if ( !img->alpha ) return; //createXMaskImage( X, img); img->qImg->setAlphaBuffer(TRUE); *(img->qImg_AlphaMask) = img->qImg->createAlphaMask(); for ( i=0; i<img->height; i++ ) { for ( j=0; j<img->width; j++ ) { a = GetAlpha( img->alpha, j, i); if ( a < threshold ) { //XPutPixel( img->xImg, j, i, 0); //XPutPixel( img->xMask, j, i, 0); DBG( AWT_IMG, printf("reduce alpha! %d %d",img->qImg->width(),img->qImg->height()) ); img->qImg->setPixel(j,i,0); } } } AWT_FREE( img->alpha->buf); AWT_FREE( img->alpha); img->alpha = 0;}#if 0static inline intinterpolate ( int ul, int ur, int ll, int lr, double dx, double dy ){ double u = ul + (double)(ur - ul) * dx; double l = ll + (double)(lr - ll) * dx; return (int) (u + (l - u) * dy + 0.5);}static unsigned intgetScaledAlpha ( Toolkit* X, Image* img, int x, int y, double dx, double dy ){ int ul, ur, ll, lr, a; int xi = (dx) ? x+1 : x; int yi = (dy) ? y+1 : y; if ( img->alpha ) { ul = GetAlpha( img->alpha, x, y); ur = GetAlpha( img->alpha, xi, y); ll = GetAlpha( img->alpha, x, yi); lr = GetAlpha( img->alpha, xi,yi); a = (unsigned int) interpolate( ul, ur, ll, lr, dx, dy); return a; } return 0xff;}static longgetScaledPixel ( Toolkit* X, Image* img, int x, int y, double dx, double dy ){ unsigned long ul, ur, ll, lr; int ulR, urR, llR, lrR, ulG, urG, llG, lrG, ulB, urB, llB, lrB, r, g, b; int xi = (dx) ? x+1 : x; int yi = (dy) ? y+1 : y; if ( img->xMask ) { ul = XGetPixel( img->xMask, x, y); ur = XGetPixel( img->xMask, xi, y); ll = XGetPixel( img->xMask, x, yi); lr = XGetPixel( img->xMask, xi,yi); if ( !interpolate( ul, ur, ll, lr, dx, dy) ) return -1; } ul = XGetPixel( img->xImg, x, y); ur = XGetPixel( img->xImg, xi, y); ll = XGetPixel( img->xImg, x, yi); lr = XGetPixel( img->xImg, xi,yi); if ( (ul == ur) && (ll == ul) && (lr == ll) ) {// rgbValues( X, ul, &r, &g, &b); } else {// rgbValues( X, ul, &ulR, &ulG, &ulB);// rgbValues( X, ur, &urR, &urG, &urB);// rgbValues( X, ll, &llR, &llG, &llB);// rgbValues( X, lr, &lrR, &lrG, &lrB); r = interpolate( ulR, urR, llR, lrR, dx, dy); g = interpolate( ulG, urG, llG, lrG, dx, dy); b = interpolate( ulB, urB, llB, lrB, dx, dy); }// return pixelValue( X, (r << 16) | (g << 8) | b); return 0;}voidinitScaledImage ( Toolkit* X, Image *tgt, Image *src, int dx0, int dy0, int dx1, int dy1, int sx0, int sy0, int sx1, int sy1 ){ double xScale, yScale, sX, sY, sxDelta, syDelta; int dx, dy, dxInc, dyInc, sx, sy; long c; dxInc = (dx1 > dx0) ? 1 : -1; dyInc = (dy1 > dy0) ? 1 : -1; dx1 += dxInc; dy1 += dyInc; xScale = (double) (dx1 - dx0) / (double) (sx1 - sx0 +1); yScale = (double) (dy1 - dy0) / (double) (sy1 - sy0 +1); for ( dy=dy0; dy != dy1; dy += dyInc ) { sY = sy0 + (dy - dy0) / yScale; sy = (int) sY; syDelta = (sy < sy1) ? sY - sy : 0; for ( dx=dx0; dx != dx1; dx += dxInc ) { sX = sx0 + (dx - dx0) / xScale; sx = (int) sX; sxDelta = (sx < sx1) ? sX - sx : 0; if ( (c = getScaledPixel( X, src, sx, sy, sxDelta, syDelta)) != -1 ){ XPutPixel( tgt->xImg, dx, dy, c); if ( src->alpha ) PutAlpha( tgt->alpha, dx, dy, getScaledAlpha( X, src, sx, sy, sxDelta, syDelta)); } else { XPutPixel( tgt->xMask, dx, dy, 0); XPutPixel( tgt->xImg, dx, dy, 0); } } }}#endif/************************************************************************************ * exported native methods */void*Java_java_awt_Toolkit_imgCreateImage ( JNIEnv* env, jclass clazz, jint width, jint height ){ printf("imgCreateImage w=%d h=%d\n",(int)width,(int)height); Image *img = createImage( width, height); createXImage( X, img); return img;}void*Java_java_awt_Toolkit_imgCreateScreenImage ( JNIEnv* env, jclass clazz, jint width, jint height ){ printf("imgCreateScreenImage w=%d h=%d\n",(int)width,(int)height); Image *img = createImage( width, height); //int depth = DefaultDepth( X->dsp, DefaultScreen( X->dsp)); //img->pix = XCreatePixmap( X->dsp, X->root, width, height, depth); img->qpm = new QPixmap(width,height); return img;}/* generic (ImageProducer) based image construction */voidJava_java_awt_Toolkit_imgSetIdxPels ( JNIEnv* env, jclass clazz, Image * img, jint x, jint y, jint w, jint h, jintArray clrMap, jbyteArray idxPels, jint trans, jint off, jint scan){ printf("imgSetIdxPels\n"); register int row, col; unsigned long pix; jint rgb; jboolean isCopy; jint *clr = env->GetIntArrayElements( clrMap, &isCopy); jbyte *pel = env->GetByteArrayElements( idxPels, &isCopy); unsigned char *idx = (unsigned char*)(pel + off); int maxCol = x + w; int maxRow = y + h; unsigned char curPel;// if ( (trans >= 0) && !img->xMask )// createXMaskImage( X, img); if ( (trans >= 0) && !img->qImg_AlphaMask) img->qImg_AlphaMask = new QImage(); for ( row = y; row < maxRow; row++) { for ( col = x; col < maxCol; col++) { curPel = idx[col + row * scan]; rgb = clr[curPel];// pix = pixelValue( X, rgb); if ( trans >= 0 ) { if ( curPel == trans ){ pix = 0; //XPutPixel( img->xMask, col, row, 0); img->qImg_AlphaMask->setPixel(col,row,0); } } //XPutPixel( img->xImg, col, row, pix); img->qImg->setPixel(col,row,rgb); } } env->ReleaseIntArrayElements( clrMap, clr, JNI_ABORT); env->ReleaseByteArrayElements( idxPels, pel, JNI_ABORT);}voidJava_java_awt_Toolkit_imgSetRGBPels ( JNIEnv* env, jclass clazz, Image * img, jint x, jint y, jint w, jint h, jintArray rgbPels, jint off, jint scan){ printf("imgSetRGBPels\n"); register int row, col; unsigned long pix = 0; jboolean isCopy; jint *rgbs = env->GetIntArrayElements( rgbPels, &isCopy); jint *rgb = rgbs + off; int maxCol = x + w; int maxRow = y + h; jint val; for ( row = y; row < maxRow; row++) { for ( col = x; col < maxCol; col++) { val = rgb[col + row * scan]; if ( (val & 0xff000000) == 0xff000000 ) {// pix = pixelValue( X, val); //XPutPixel( img->xImg, col, row, pix); img->qImg->setPixel(col,row,val); } else { /* * No way to tell for now if this will be a reduced (on/off) or a * full alpha channel. We have to be prepared for the "worst", and reduce * later */ if ( !img->alpha )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -