/* A* ------------------------------------------------------------------- B* This file contains source code for the PyMOL computer program C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. D* ------------------------------------------------------------------- E* It is unlawful to modify or remove this copyright notice. F* ------------------------------------------------------------------- G* Please see the accompanying LICENSE file for further information. H* ------------------------------------------------------------------- I* Additional authors of this source file include: -* -* -* Z* ------------------------------------------------------------------- */ #include "Pixmap.h" #include "OOMac.h" #include "Util.h" void PixmapInit(PyMOLGlobals * G, CPixmap * I, int width, int height) { UtilZeroMem(I, sizeof(CPixmap)); I->G = G; I->height = height; I->width = width; if((height >= 0) && (width >= 0)) { I->buffer = Alloc(unsigned char, 4 * height * width); } } CPixmap *PixmapNew(PyMOLGlobals * G, int width, int height) { OOAlloc(G, CPixmap); PixmapInit(G, I, width, height); return I; } void PixmapInitFromBitmap(PyMOLGlobals * G, CPixmap * I, int width, int height, unsigned char *bitmap, unsigned char *rgba, int sampling) { if(I) { int x, y, bit_cnt; unsigned char cur = 0; unsigned char *src; unsigned char *dst; register unsigned char red, blue, green, alpha; PixmapInit(G, I, width * sampling, height * sampling); red = rgba[0]; green = rgba[1]; blue = rgba[2]; alpha = rgba[3]; UtilZeroMem(I->buffer, 4 * width * height); src = bitmap; dst = I->buffer; for(y = 0; y < height; y++) { bit_cnt = 7; for(x = 0; x < width; x++) { bit_cnt++; if(bit_cnt > 7) { cur = *(src++); bit_cnt = 0; } if(cur & 0x80) { *(dst++) = red; *(dst++) = green; *(dst++) = blue; *(dst++) = alpha; } else { *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; } cur <<= 1; } } if(sampling > 1) { unsigned int *p, *pp, *q, *row; int row_cnt, col_cnt, width_sampling = width * sampling; p = (unsigned int *) (I->buffer + 4 * width * height); q = (unsigned int *) (I->buffer + 4 * width * height * sampling * sampling); while(p > (unsigned int *) I->buffer) { row_cnt = sampling - 1; row = q; for(x = 0; x < width; x++) { /* first row */ col_cnt = sampling; p--; while(col_cnt--) { *(--q) = *p; } } if(row_cnt) { while(row_cnt--) { /* remaining rows */ pp = row; for(x = 0; x < width_sampling; x++) { *(--q) = *(--pp); } } } } } } } void PixmapInitFromBytemap(PyMOLGlobals * G, CPixmap * I, int width, int height, int pitch, unsigned char *bytemap, unsigned char *rgba, unsigned char *outline_rgb, int flat) { if(I) { int x, y; unsigned char *src, *sa, alp; unsigned char *dst; register unsigned char red, blue, green, alpha, no_alpha; register unsigned char ored = 0, oblue = 0, ogreen = 0; if(!outline_rgb[3]) outline_rgb = NULL; else { ored = outline_rgb[0]; oblue = outline_rgb[1]; ogreen = outline_rgb[2]; } PixmapInit(G, I, width, height); red = rgba[0]; green = rgba[1]; blue = rgba[2]; alpha = rgba[3]; UtilZeroMem(I->buffer, 4 * width * height); src = bytemap; dst = I->buffer; no_alpha = flat; for(y = 0; y < height; y++) { sa = src; if(no_alpha) { for(x = 0; x < width; x++) { alp = *(sa++); if(alp) { *(dst++) = red; *(dst++) = green; *(dst++) = blue; *(dst++) = 0xFF; } else { *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; } } } else { for(x = 0; x < width; x++) { if(outline_rgb) { unsigned char amax = 0, amin; if(y > 0) { alp = 255 - *(sa - pitch); } else { alp = 255; } if(amax < alp) amax = alp; if(y < (height - 1)) { alp = 255 - *(sa + pitch); } else { alp = 255; } if(amax < alp) amax = alp; if(x > 0) { alp = 255 - *(sa - 1); } else { alp = 255; } if(amax < alp) amax = alp; if(x < (width - 1)) { alp = 255 - *(sa + 1); } else { alp = 255; } if(amax < alp) amax = alp; amin = 255 - amax; alp = *(sa++); if(alp) { *(dst++) = (red * amin + ored * amax) / 255; *(dst++) = (green * amin + ogreen * amax) / 255; *(dst++) = (blue * amin + oblue * amax) / 255; *(dst++) = (alpha * alp) / 255; } else { *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; } } else { alp = *(sa++); if(alp) { *(dst++) = red; *(dst++) = green; *(dst++) = blue; *(dst++) = (alpha * alp) >> 8; } else { *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; *(dst++) = 0; } } } } src += pitch; } } } void PixmapPurge(CPixmap * I) { if(I) { FreeP(I->buffer); } } void PixmapFreeP(CPixmap * I) { PixmapPurge(I); OOFreeP(I); }