mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-03 19:54:24 +08:00
236 lines
6.0 KiB
C++
236 lines
6.0 KiB
C++
|
|
|
|
/*
|
|
A* -------------------------------------------------------------------
|
|
B* This file contains source code for the PyMOL computer program
|
|
C* Copyright (c) Schrodinger, LLC.
|
|
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 "MemoryDebug.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 = pymol::malloc<unsigned char>(4 * height * width);
|
|
}
|
|
}
|
|
|
|
CPixmap *PixmapNew(PyMOLGlobals * G, int width, int height)
|
|
{
|
|
auto I = new 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;
|
|
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;
|
|
unsigned char red, blue, green, alpha, no_alpha;
|
|
unsigned char ored = 0, oblue = 0, ogreen = 0;
|
|
if(!outline_rgb[3])
|
|
outline_rgb = nullptr;
|
|
else {
|
|
ored = outline_rgb[0];
|
|
ogreen = outline_rgb[1];
|
|
oblue = 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);
|
|
DeleteP(I);
|
|
}
|