blob: 00a2a0cd3a75448546df8505047ab7a4f66a04e3 [file] [log] [blame]
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1998--1999 Guido Masarotto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, a copy is available at
* https://www.R-project.org/Licenses/
*/
/*
bitmap -> image conversion
Very easy to write: routines here are the graphapp
image to image conversion routines with assignement
changed.
*/
#include "ga.h"
/*
* Try to generate an 8-bit version.
* If there are less than 256 unique colours
* this routine will return the corresponding
* indexed 8-bit image.
* Returns NULL if more than 256 colours are found.
*/
static image copy2image8 (drawing dw)
{
image new_img;
long x, y, w, h, j;
GAbyte * pixel8;
int cmapsize;
int low, high, mid;
rgb col;
rgb cmap[256];
point p;
w = getwidth(dw);
h = getheight(dw);
/* the first colour goes into the cmap automatically: */
cmapsize = 0; mid = 0;
for (y = 0; y < h; y++) {
p.y = y;
for (x = 0; x < w; x++) {
p.x = x;
col = ggetpixel(dw, p);
/* only allow one transparent colour in the cmap: */
if (col & 0xF0000000UL)
col = 0xFFFFFFFFUL; /* transparent */
else
col &= 0x00FFFFFFUL; /* opaque */
/* binary search the cmap: */
low = 0; high = cmapsize - 1;
while (low <= high) {
mid = (low + high)/2;
if (col < cmap[mid]) high = mid - 1;
else if (col > cmap[mid]) low = mid + 1;
else break;
}
if (high < low) {
/* didn't find colour in cmap, insert it: */
if (cmapsize >= 256)
return NULL;
for (j = cmapsize; j > low; j--)
cmap[j] = cmap[j-1];
cmap[low] = col;
cmapsize ++;
}
}
}
/* now create the 8-bit indexed image: */
new_img = newimage(w, h, 8);
if (! new_img)
return new_img;
setpalette(new_img, cmapsize, cmap);
/* now convert each 32-bit pixel into an 8-bit pixel: */
pixel8 = (GAbyte *) new_img->pixels;
for (y = 0; y < h; y++) {
p.y = y;
for (x = 0; x < w; x++) {
p.x = x;
col = ggetpixel(dw, p);
/* only allow one transparent colour in the cmap: */
if (col & 0xF0000000UL)
col = 0xFFFFFFFFUL; /* transparent */
else
col &= 0x00FFFFFFUL; /* opaque */
/* binary search the cmap (the colour must be there): */
low = 0; high = cmapsize - 1;
while (low <= high) {
mid = (low + high)/2;
if (col < cmap[mid]) high = mid - 1;
else if (col > cmap[mid]) low = mid + 1;
else break;
}
if (high < low) {
/* impossible situation */
delimage(new_img);
return NULL;
}
*(pixel8++) = mid;
}
}
return new_img;
}
/*
* Try to generate a 32-bit version.
* Return NULL if there is no memory left.
*/
static image copy2image32 (drawing dw)
{
image new_img;
rgb *pixel32;
long x, y, w, h;
point p;
w = getwidth(dw);
h = getheight(dw);
new_img = newimage(w, h, 32);
if (! new_img)
return new_img;
pixel32 = (rgb *) new_img->pixels;
for (y = 0; y < h; y++) {
p.y = y;
for (x = 0; x < w; x++) {
p.x = x;
*(pixel32++) = ggetpixel(dw, p);
}
}
return new_img;
}
/*
* Try to generate an image (with depth 8 or 32) from drawing dw:
* Return NULL on failure.
*/
image bitmaptoimage (drawing dw)
{
image new_img;
rect r = ggetcliprect(dw);
gsetcliprect(dw, getrect(dw));
new_img = copy2image8(dw);
if (!new_img)
new_img = copy2image32(dw);
gsetcliprect(dw, r);
return new_img;
}