1 /* new.c:
2  *
3  * functions to allocate and deallocate structures and structure data
4  *
5  * jim frost 09.29.89
6  *
7  * Copyright 1989, 1991 Jim Frost.
8  * See included file "copyright.h" for complete copyright information.
9  */
10 
11 #include "copyright.h"
12 #include "image.h"
13 #ifdef HAVE_MALLOC_H
14 #include <malloc.h>
15 #endif
16 
17 extern int _Xdebug;
18 
19 /* this table is useful for quick conversions between depth and ncolors
20  */
21 
22 unsigned long DepthToColorsTable[] = {
23   /*  0 */ 1,
24   /*  1 */ 2,
25   /*  2 */ 4,
26   /*  3 */ 8,
27   /*  4 */ 16,
28   /*  5 */ 32,
29   /*  6 */ 64,
30   /*  7 */ 128,
31   /*  8 */ 256,
32   /*  9 */ 512,
33   /* 10 */ 1024,
34   /* 11 */ 2048,
35   /* 12 */ 4096,
36   /* 13 */ 8192,
37   /* 14 */ 16384,
38   /* 15 */ 32768,
39   /* 16 */ 65536,
40   /* 17 */ 131072,
41   /* 18 */ 262144,
42   /* 19 */ 524288,
43   /* 20 */ 1048576,
44   /* 21 */ 2097152,
45   /* 22 */ 4194304,
46   /* 23 */ 8388608,
47   /* 24 */ 16777216,
48   /* 25 */ 33554432,
49   /* 26 */ 67108864,
50   /* 27 */ 134217728,
51   /* 28 */ 268435456,
52   /* 29 */ 536870912,
53   /* 30 */ 1073741824,
54   /* 31 */ 2147483648UL,
55   /* 32 */ 2147483648UL /* bigger than unsigned int; this is good enough */
56 };
57 
colorsToDepth(ncolors)58 unsigned long colorsToDepth(ncolors)
59      unsigned long ncolors;
60 { unsigned long a;
61 
62   for (a= 0; (a < 32) && (DepthToColorsTable[a] < ncolors); a++)
63     /* EMPTY */
64     ;
65   return(a);
66 }
67 
68 
ovmul(unsigned int a,unsigned int b)69 static unsigned int ovmul(unsigned int a, unsigned int b)
70 {
71   unsigned int r;
72 
73   r = a * b;
74   if (r / a != b) {
75     memoryExhausted();
76   }
77 
78   return r;
79 }
80 
goodImage(image,func)81 void goodImage(image, func)
82      Image *image;
83      char  *func;
84 {
85   if (!image) {
86     printf("%s: nil image\n", func);
87     exit(0);
88   }
89   switch (image->type) {
90   case IBITMAP:
91   case IRGB:
92   case ITRUE:
93     break;
94   default:
95     printf("%s: bad destination image\n", func);
96     exit(0);
97   }
98 }
dupString(s)99 char *dupString(s)
100      char *s;
101 { char *d;
102 
103   if (!s)
104     return(NULL);
105   d= (char *)lmalloc(strlen(s) + 1);
106   strcpy(d, s);
107   return(d);
108 }
109 
newRGBMapData(rgb,size)110 void newRGBMapData(rgb, size)
111      RGBMap       *rgb;
112      unsigned int  size;
113 {
114   rgb->used= 0;
115   rgb->size= size;
116   rgb->compressed= 0;
117   rgb->red= (Intensity *)lmalloc(sizeof(Intensity) * size);
118   rgb->green= (Intensity *)lmalloc(sizeof(Intensity) * size);
119   rgb->blue= (Intensity *)lmalloc(sizeof(Intensity) * size);
120 }
121 
freeRGBMapData(rgb)122 void freeRGBMapData(rgb)
123      RGBMap *rgb;
124 {
125   lfree((byte *)rgb->red);
126   lfree((byte *)rgb->green);
127   lfree((byte *)rgb->blue);
128 }
129 
newBitImage(width,height)130 Image *newBitImage(width, height)
131      unsigned int width, height;
132 { Image        *image;
133   unsigned int  linelen;
134 
135   image= (Image *)lmalloc(sizeof(Image));
136   image->type= IBITMAP;
137   image->title= NULL;
138   newRGBMapData(&(image->rgb), (unsigned int)2);
139   *(image->rgb.red)= *(image->rgb.green)= *(image->rgb.blue)= 65535;
140   *(image->rgb.red + 1)= *(image->rgb.green + 1)= *(image->rgb.blue + 1)= 0;
141   image->rgb.used= 2;
142   image->width= width;
143   image->height= height;
144   image->depth= 1;
145   linelen= (width / 8) + (width % 8 ? 1 : 0); /* thanx johnh@amcc.com */
146   image->data= (unsigned char *)lcalloc(ovmul(linelen, height));
147   return(image);
148 }
149 
newRGBImage(width,height,depth)150 Image *newRGBImage(width, height, depth)
151      unsigned int width, height, depth;
152 { Image        *image;
153   unsigned int  pixlen, numcolors;
154 
155   pixlen= (depth / 8) + (depth % 8 ? 1 : 0);
156   if (pixlen == 0) /* special case for `zero' depth image, which is */
157     pixlen= 1;     /* sometimes interpreted as `one color' */
158   numcolors = depthToColors(depth);
159   image= (Image *)lmalloc(sizeof(Image));
160   image->type= IRGB;
161   image->title= NULL;
162   newRGBMapData(&(image->rgb), numcolors);
163   image->width= width;
164   image->height= height;
165   image->depth= depth;
166   image->pixlen= pixlen;
167   image->data= (unsigned char *)lmalloc(ovmul(ovmul(width, height), pixlen));
168   return(image);
169 }
170 
newTrueImage(width,height)171 Image *newTrueImage(width, height)
172      unsigned int width, height;
173 { Image        *image;
174 
175   image= (Image *)lmalloc(sizeof(Image));
176   image->type= ITRUE;
177   image->title= NULL;
178   image->rgb.used= image->rgb.size= 0;
179   image->width= width;
180   image->height= height;
181   image->depth= 24;
182   image->pixlen= 3;
183   image->data= (unsigned char *)lmalloc(ovmul(ovmul(width, height), 3));
184   image->data= (unsigned char *)lmalloc(width * height * 3);
185   return(image);
186 }
187 
freeImageData(image)188 void freeImageData(image)
189      Image *image;
190 {
191   if (image->title) {
192     lfree((byte *)image->title);
193     image->title= NULL;
194   }
195   if (!TRUEP(image))
196     freeRGBMapData(&(image->rgb));
197   lfree(image->data);
198 }
199 
freeImage(image)200 void freeImage(image)
201      Image *image;
202 {
203   goodImage(image, "freeImage");
204   freeImageData(image);
205   image->type= IBAD;
206   lfree((byte *)image);
207 }
208 
lmalloc(size)209 byte *lmalloc(size)
210      unsigned int size;
211 { byte *area;
212 
213   if (size == 0) {
214     size= 1;
215     if (_Xdebug)
216       fprintf(stderr, "lcalloc given zero size!\n");
217   }
218   if (!(area= (byte *)malloc(size))) {
219     memoryExhausted();
220     /* NOTREACHED */
221   }
222   return(area);
223 }
224 
lcalloc(size)225 byte *lcalloc(size)
226      unsigned int size;
227 { byte *area;
228 
229   if (size == 0) {
230     size= 1;
231     if (_Xdebug)
232       fprintf(stderr, "lcalloc given zero size!\n");
233   }
234   if (!(area= (byte *)calloc(1, size))) {
235     memoryExhausted();
236     /* NOTREACHED */
237   }
238   return(area);
239 }
240 
lfree(area)241 void lfree(area)
242      byte *area;
243 {
244   free(area);
245 }
246