The R Project SVN R

Rev

Rev 68956 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4394 ripley 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1998--1999  Guido Masarotto
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
42300 ripley 16
 *  along with this program; if not, a copy is available at
68956 ripley 17
 *  https://www.R-project.org/Licenses/
4394 ripley 18
 */
19
 
20
/*
21
   bitmap -> image conversion
22
   Very easy to write: routines here are the graphapp
23
   image to image conversion routines with assignement
24
   changed.
25
 */
26
 
27
#include "ga.h"
28
 
29
/*
30
 *  Try to generate an 8-bit version.
31
 *  If there are less than 256 unique colours
32
 *  this routine will return the corresponding
33
 *  indexed 8-bit image.
34
 *  Returns NULL if more than 256 colours are found.
35
 */
36
static image copy2image8 (drawing dw)
45067 ripley 37
{
4394 ripley 38
    image new_img;
39
    long   x, y, w, h, j;
76910 kalibera 40
    GAbyte * pixel8;
4394 ripley 41
    int    cmapsize;
42
    int low, high, mid;
43
    rgb    col;
44
    rgb    cmap[256];
45
    point p;
46
    w = getwidth(dw);
47
    h = getheight(dw);
48
    /* the first colour goes into the cmap automatically: */
49
    cmapsize = 0;  mid = 0;
50
 
51
    for (y = 0; y < h; y++) {
52
	p.y = y;
53
	for (x = 0; x < w; x++) {
54
	    p.x = x;
5278 ripley 55
	    col = ggetpixel(dw, p);
4394 ripley 56
	    /* only allow one transparent colour in the cmap: */
57
	    if (col & 0xF0000000UL)
58
		col  = 0xFFFFFFFFUL;	/* transparent */
59
	    else
60
		col &= 0x00FFFFFFUL;	/* opaque */
61
	    /* binary search the cmap: */
62
	    low = 0;  high = cmapsize - 1;
63
	    while (low <= high) {
5278 ripley 64
		mid = (low + high)/2;
4394 ripley 65
		if      (col < cmap[mid]) high = mid - 1;
66
		else if (col > cmap[mid]) low  = mid + 1;
67
		else break;
68
	    }
69
 
70
	    if (high < low) {
71
		/* didn't find colour in cmap, insert it: */
72
		if (cmapsize >= 256)
73
		    return NULL;
5278 ripley 74
		for (j = cmapsize; j > low; j--)
4394 ripley 75
		    cmap[j] = cmap[j-1];
76
		cmap[low] = col;
77
		cmapsize ++;
78
	    }
79
	}
80
    }
81
 
82
    /* now create the 8-bit indexed image: */
83
 
84
    new_img = newimage(w, h, 8);
85
    if (! new_img)
86
	return new_img;
87
    setpalette(new_img, cmapsize, cmap);
88
    /* now convert each 32-bit pixel into an 8-bit pixel: */
89
 
76910 kalibera 90
    pixel8 = (GAbyte *) new_img->pixels;
4394 ripley 91
 
5278 ripley 92
    for (y = 0; y < h; y++) {
93
	p.y = y;
94
	for (x = 0; x < w; x++) {
95
	    p.x =  x;
96
	    col = ggetpixel(dw, p);
97
	    /* only allow one transparent colour in the cmap: */
98
	    if (col & 0xF0000000UL)
99
		col  = 0xFFFFFFFFUL;	/* transparent */
100
	    else
101
		col &= 0x00FFFFFFUL;	/* opaque */
102
	    /* binary search the cmap (the colour must be there): */
103
	    low = 0;  high = cmapsize - 1;
104
	    while (low <= high) {
105
		mid = (low + high)/2;
106
		if      (col < cmap[mid]) high = mid - 1;
107
		else if (col > cmap[mid]) low  = mid + 1;
108
		else break;
109
	    }
4394 ripley 110
 
5278 ripley 111
	    if (high < low) {
112
		/* impossible situation */
113
		delimage(new_img);
114
		return NULL;
115
	    }
116
	    *(pixel8++) = mid;
117
	}
4394 ripley 118
    }
119
    return new_img;
120
}
121
 
122
 
123
/*
124
 *  Try to generate a 32-bit version.
125
 *  Return NULL if there is no memory left.
126
 */
127
static image copy2image32 (drawing dw)
128
{
129
    image new_img;
130
    rgb *pixel32;
131
    long  x, y, w, h;
132
    point p;
133
    w = getwidth(dw);
134
    h = getheight(dw);
135
    new_img = newimage(w, h, 32);
136
    if (! new_img)
137
	return new_img;
138
 
139
    pixel32 = (rgb *) new_img->pixels;
140
    for (y = 0; y < h; y++) {
141
	p.y = y;
142
	for (x = 0; x < w; x++) {
143
	    p.x = x;
5278 ripley 144
	    *(pixel32++) = ggetpixel(dw, p);
4394 ripley 145
	}
146
    }
147
    return new_img;
148
}
149
 
150
 
151
 
152
/*
153
 *  Try to generate an image (with depth 8 or 32)  from drawing dw:
154
 *  Return NULL on failure.
155
 */
156
image bitmaptoimage (drawing dw)
157
{
158
    image new_img;
5249 guido 159
    rect r = ggetcliprect(dw);
5278 ripley 160
 
5249 guido 161
    gsetcliprect(dw, getrect(dw));
4394 ripley 162
    new_img = copy2image8(dw);
163
    if (!new_img)
164
	new_img = copy2image32(dw);
5249 guido 165
    gsetcliprect(dw, r);
4394 ripley 166
    return new_img;
167
}