📄 images.c
字号:
/* width * height * 4 gives us the size of a 32 bpp image */ imgLen = nWidth * nHeight << 2; srcImgLen = imageWidth * imageHeight << 2; if(transform & TRANSFORM_INVERTED_AXES) { t_width = nHeight; t_height = nWidth; } else { t_width = nWidth; t_height = nHeight; } if (transform & TRANSFORM_Y_FLIP) { yStart = nHeight-1; yIncr = -1; } else { yStart = 0; yIncr = +1; } if (transform & TRANSFORM_X_FLIP) { xStart = nWidth-1; xIncr = -1; } else { xStart = 0; xIncr = +1; } /* increment srcX,Y regular. increment destX,Y according to transform. this makes handling of mask and alpha values easier */ for (srcY = nYOriginSrc, destY = yStart, yCounter = 0; yCounter < nHeight; srcY++, destY+=yIncr, yCounter++) { /* in the current implementation we have source bitmap dimension as the width of the image and the height of the region destination bitmap is of the dimensions of the region */ for (srcX = nXOriginSrc, destX = xStart, xCounter = 0; xCounter < nWidth; srcX++, destX+=xIncr, xCounter++) { if ( transform & TRANSFORM_INVERTED_AXES ) { /* copy the pixel that is pointed to */ XPutPixel(&destP->bitmap->image, destY, destX, XGetPixel(&sourceBitmap->image, srcX, srcY)); } else { /* copy the pixel that is pointed to */ XPutPixel(&destP->bitmap->image, destX, destY, XGetPixel(&sourceBitmap->image, srcX, srcY)); } } /*for x*/ } /* for y */ /* --- */}static void*imageDone(imageDstPtr self, int *width, int *height){ _imageDstPtr p = (_imageDstPtr)self; if (p == NULL) return; if ((width != NULL) && (height != NULL)) { *width = p->bitmap->width; *height = p->bitmap->height; } return (void*)p->bitmap;}/* * Dither matrices. * * canonical matrix is * { 0, 6, 9, 15}, * {11, 13, 2, 4}, * { 7, 1, 14, 8}, * {12, 10, 5, 3} * * or, converted to signed: * * {-8, -2, 1, 7}, * { 3, 5, -6, -4}, * {-1, -7, 6, 0}, * { 4, 2, -3, -5} * */static signed char cmat[4][4] = { {-24, -6, 3, 21}, { 9, 15, -18, -12}, { -3, -21, 18, 0}, { 12, 6, -9, -15}};static voidblendPixel(int *r, int *g, int *b, int *alpha, int off){#if USE_ALPHA_BLEND if (*alpha < TRANS_THRESHOLD) { *alpha = 0; }#if TRANS_BINARY_THRESHOLD else { *alpha = 0xff; }#endif *r = (*r * *alpha) / 0xff; *g = (*g * *alpha) / 0xff; *b = (*b * *alpha) / 0xff;#else /* USE_ALPHA_BLEND */ /* * if we're not using alphablending then dither the alpha * values so we can approximate a blending effect */ if ((*alpha != 0x00) && (*alpha != 0xff)) { *alpha += off * 3; if (*alpha < TRANS_THRESHOLD) { *alpha = 0; } else { *alpha = 0xff; } }#endif}/* * build a bit mask for dealing with transparent images that either * only have pixels that are on or off or are dithering an alpha blend * */static voidbuildMask(myBitmapStruct *bitmap, int alpha, int x, int y){ /* the mask must be 8-bit aligned for myPtImageMask */ int width = bitmap->width + (8 - (bitmap->width & 7)); if (bitmap->imageMask == NULL) { int len = (width >> 3) * bitmap->height; bitmap->imageMask = (unsigned char *)midpCalloc(len, sizeof(char)); } if (bitmap->imageMask != NULL) { /* * build the image mask */ int offset = (y * width + x) >> 3; *(bitmap->imageMask + offset) |= (alpha & 1) << (7 - (x & 7)); }}static voidbuildAlphaChannel(myBitmapStruct *bitmap, int alpha, int x, int y) { if (bitmap->imageMask == NULL) { int len = bitmap->width * bitmap->height; bitmap->imageMask = (unsigned char *)midpCalloc(len, sizeof(char)); } if (bitmap->imageMask != NULL) { int offset = y * bitmap->width + x; *(bitmap->imageMask + offset) = (unsigned char)(alpha & 0xff); }}static void setARGBPixels(imageDstPtr self, int** imageBuf, int bufLen, int width, int height, jboolean useAlpha){ int x; int y; int offset; int pixel; int alpha; int r; int g; int b; _imageDstPtr p = (_imageDstPtr)self; if ((p->bitmap == NULL) || (p->mutable)){ fprintf(stderr, "setARGBPixel error\n"); return; } if (useAlpha) { p->bitmap->prop = HAS_ALPHA; } for (y = 0; y < height; y++){ for (x = 0; x < width; x++){ offset = (y * width) + x; pixel = (*imageBuf)[offset]; alpha = (pixel >> 24) & 0xff; r = (pixel >> 16) & 0xff; g = (pixel >> 8 ) & 0xff; b = pixel & 0xff; XPutPixel(&p->bitmap->image, x, y, getPixelValue(r, g, b)); if (useAlpha){ buildAlphaChannel(p->bitmap, alpha, x, y); } } }}static voidsendPixelsColor(imageDstPtr self, int y, uchar *pixels, int pixelType){ int x; signed char *mat = cmat[y & 3]; _imageDstPtr p = (_imageDstPtr)self; if ((p->bitmap == NULL) || (p->mutable)) return; if ((pixelType == CT_COLOR) || /* color triplet */ (pixelType == (CT_COLOR | CT_ALPHA))) { /* color triplet with alpha */ for (x = 0; x < p->bitmap->width; ++x) { int off = mat[x & 3]; int r = pixels[0]; int g = pixels[1]; int b = pixels[2]; int alpha = 0xff; if (pixelType & CT_ALPHA) { alpha = pixels[3]; p->bitmap->prop = HAS_ALPHA; pixels++; } else if (p->hasTransMap) { alpha = pixels[3]; p->bitmap->prop = HAS_ALPHA; pixels++; } pixels += 3; r += off; g += off; b += off; if (r < 0) r = 0; else if (r > 0xff) r = 0xff; if (g < 0) g = 0; else if (g > 0xff) g = 0xff; if (b < 0) b = 0; else if (b > 0xff) b = 0xff; if (p->bitmap->prop == HAS_ALPHA) { blendPixel(&r, &g, &b, &alpha, off); }#if USE_ALPHA_BLEND if (p->bitmap->prop == HAS_MASK) { buildMask(p->bitmap, alpha, x, y); } else if (p->bitmap->prop == HAS_ALPHA) { buildAlphaChannel(p->bitmap, alpha, x, y); }#else if (p->bitmap->prop == HAS_MASK || p->bitmap->prop == HAS_ALPHA) { buildMask(p->bitmap, alpha, x, y); } #endif XPutPixel(&p->bitmap->image, x, y, getPixelValue(r, g, b)); } } else { /* indexed color */ for (x = 0; x < p->bitmap->width; ++x) { int off = mat[x & 3]; int cmapIndex = *pixels++; int color = p->cmap[cmapIndex]; int r = ((color >> 16) & 0xff) + off; int g = ((color >> 8) & 0xff) + off; int b = ((color >> 0) & 0xff) + off; int alpha = 0xff; if (r < 0) r = 0; else if (r > 0xff) r = 0xff; if (g < 0) g = 0; else if (g > 0xff) g = 0xff; if (b < 0) b = 0; else if (b > 0xff) b = 0xff; if ((pixelType & (CT_ALPHA | CT_COLOR)) == CT_ALPHA) { alpha = *pixels++; p->bitmap->prop = HAS_ALPHA; } else if (p->hasTransMap) { if ((pixelType & CT_COLOR) == 0) { /* grayscale */ alpha = *pixels++; p->bitmap->prop = HAS_ALPHA; } else { /* indexed color */ alpha = p->tmap[cmapIndex]; p->bitmap->prop = HAS_ALPHA; } } if (p->bitmap->prop == HAS_ALPHA) { blendPixel(&r, &g, &b, &alpha, off); }#if USE_ALPHA_BLEND if (p->bitmap->prop == HAS_MASK) { buildMask(p->bitmap, alpha, x, y); } else if (p->bitmap->prop == HAS_ALPHA) { buildAlphaChannel(p->bitmap, alpha, x, y); }#else if (p->bitmap->prop == HAS_MASK || p->bitmap->prop == HAS_ALPHA) { buildMask(p->bitmap, alpha, x, y); } #endif XPutPixel(&p->bitmap->image, x, y, getPixelValue(r, g, b)); } } }static voidsendPackedPixelsColor(imageDstPtr self, int y, uchar *pixels){ /* * since we specified a depth of 8, these must be * pixels in 8-bit grayscale. pngDecode gives us a * colormap for that case, so... */ sendPixelsColor(self, y, pixels, KNI_FALSE);}imageDstPtr LCDUIcreateImageDst(jboolean mutable) { _imageDstPtr p = midpMalloc(sizeof(_imageDstData)); if (p == NULL) { return NULL; } p->super.ptr = p; p->super.depth = 8; p->super.setColormap = setImageColormap; p->super.setTransMap = setImageTransparencyMap; p->super.setSize = setImageSize; p->super.sendPixels = sendPixelsColor; p->super.sendPackedPixels = sendPackedPixelsColor; p->super.copyPixels = copyImagePixels; p->super.done = imageDone; p->super.setARGBPixels = setARGBPixels; p->super.copyPixelsTransformed = copyPixelsTransform; if ((p->bitmap=(myBitmapStruct*)midpCalloc(sizeof(myBitmapStruct),1)) == NULL) { midpFree(p); return NULL; } p->mutable = mutable; p->hasColormap = KNI_FALSE; p->hasTransMap = KNI_FALSE; return (imageDstPtr)p;}#define XDRAWPOINT(dx) \ XPutPixel(dest, x + dx, y, XGetPixel(image, x + dx, y)); static voidmyPutImageMask(Display *display, Drawable d, GC gc, XImage *image, unsigned char *mask, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height){ int i, x, y; unsigned char data; unsigned char *maskPtr = mask; XImage *dest; dest = XGetImage(display, d, dest_x, dest_y, width, height, 0xff, ZPixmap); if (dest == NULL || mask == NULL) { XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height); if (dest != NULL) { XDestroyImage(dest); } return; } /* it won't matter if the new width is larger than the actual bitmap * since invalid bitmap locations will have 0 in the corresponding * mask position and therefore won't be accesed */ width = width + (8 - (width & 7)); for (y = 0; y < height; y++) { for (x = 0; x < width; x += 8) { data = *maskPtr++; if (data == 0xff) { /* * all the bits in the mask are set so just put all the pixels */ XDRAWPOINT(0); XDRAWPOINT(1); XDRAWPOINT(2); XDRAWPOINT(3); XDRAWPOINT(4); XDRAWPOINT(5); XDRAWPOINT(6); XDRAWPOINT(7); } else if ((data & 0xf0) == 0xf0) { /* * only half of the pixels are definitely set so put those * and then run through the others */ XDRAWPOINT(0); XDRAWPOINT(1); XDRAWPOINT(2); XDRAWPOINT(3); for (i = 4; i < 8; i++) { if (data & (1 << (7-i))) { XDRAWPOINT(i); } } } else if ((data & 0x0f) == 0x0f) { /* * the other half of the pixels are definitely set so * run through the first set and put the rest */ for (i = 0; i < 4; i++) { if (data & (1 << (7-i))) { XDRAWPOINT(i); } } XDRAWPOINT(4); XDRAWPOINT(5); XDRAWPOINT(6); XDRAWPOINT(7); } else if (data != 0x00) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -