OSDN Git Service

wwww
[proj16/16.git] / src / lib / bitmap.c
1 /* Project 16 Source Code~
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
3  *
4  * This file is part of Project 16.
5  *
6  * Project 16 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Project 16 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,
19  * Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include <stdio.h>\r
24 #include <stdlib.h>
25 #include <malloc.h>
26 #include "src/lib/bitmap.h"\r
27 #include "src/lib/modex16.h"\r
28 \r
29 static struct pcxHeader {\r
30     byte id;\r
31     byte version;\r
32     byte encoding;\r
33     byte bpp;\r
34     word xmin;\r
35     word ymin;\r
36     word xmax;\r
37     word ymax;\r
38     word hres;\r
39     word vres;\r
40     byte pal16[48];\r
41     byte res1;\r
42     word bpplane;\r
43     word palType;\r
44     word hScreenSize;\r
45     word vScreenSize;\r
46     byte padding[54];\r
47 } head;\r
48 \r
49 \r
50 static void loadPcxStage1(FILE *file, bitmap_t *result) {\r
51     long bufSize;\r
52     int index;\r
53     byte count, val;\r
54     long int pos;\r
55 \r
56     /* read the header */\r
57     fread(&head, sizeof(char), sizeof(struct pcxHeader), file);\r
58 \r
59     /* get the width and height */\r
60     result->width = head.xmax - head.xmin + 1;\r
61     result->height = head.ymax - head.ymin + 1;\r
62 \r
63     /* make sure this  is 8bpp */\r
64     if(head.bpp != 8) {\r
65                 printf("I only know how to handle 8bpp pcx files!\n");\r
66                 fclose(file);\r
67                 exit(-2);\r
68     }\r
69 }\r
70 \r
71 \r
72 static void loadPcxPalette(FILE *file, bitmap_t *result) {\r
73     byte val;\r
74     int index;\r
75 \r
76     /* handle the palette */\r
77     fseek(file, -769, SEEK_END);\r
78     val = fgetc(file);\r
79     result->palette = modexNewPal();\r
80     if(head.version == 5 && val == 12) {\r
81         /* use the vga palette */\r
82         for(index=0; !feof(file) && index < PAL_SIZE; index++) {\r
83             val = fgetc(file);\r
84             result->palette[index] = val >> 2;\r
85         }\r
86     } else {\r
87         /* use the 16 color palette */\r
88         for(index=0; index<48; index++) {\r
89             result->palette[index]  = head.pal16[index];\r
90         }\r
91     }\r
92 }\r
93 \r
94 \r
95 bitmap_t\r
96 bitmapLoadPcx(char *filename) {\r
97     FILE *file;\r
98     bitmap_t result;\r
99     dword bufSize;\r
100     int index;\r
101     byte count, val;
102 \r
103     /* open the PCX file for reading */\r
104     file = fopen(filename, "rb");\r
105     if(!file) {\r
106                 printf("Could not open %s for reading.\n", filename);\r
107                 exit(-2);\r
108     }\r
109 \r
110     /* load the first part of the pcx file */\r
111     loadPcxStage1(file, &result);
112 \r
113         /* allocate the buffer */
114         //printf("%zu\n", _memmax());\r
115         bufSize = (/*(dword)*/result.width * result.height);
116         result.data = malloc(bufSize);
117 //      result.data = (byte far *)_fmalloc(bufSize);
118 //      result.data = (byte __huge *)halloc(bufSize, sizeof(byte));
119         /*printf("&bufSize=%p\n", &bufSize);
120         printf("&result.data=%p\n", result.data);
121         printf("Size of block is %zu bytes\n", _msize(result.data));
122         printf("Size of bufSize is %zu bytes\n", bufSize);
123         printf("Size of result.width is %zu \n", result.width);
124         printf("Size of result.height is %zu \n", result.height);
125         printf("Dimensions of result is %lu\n", (dword)result.width*result.height);*/
126         //exit(0);
127         if(!result.data) {
128                 fprintf(stderr, "Could not allocate memory for bitmap data.");\r
129                 fclose(file);\r
130                 exit(-1);\r
131         }\r
132 \r
133     /*  read the buffer in */\r
134     index = 0;\r
135     do {\r
136         /* get the run length and the value */\r
137         count = fgetc(file);\r
138         if(0xC0 ==  (count & 0xC0)) { /* this is the run count */\r
139                 count &= 0x3f;\r
140                 val = fgetc(file);\r
141         } else {\r
142                 val = count;\r
143                 count = 1;\r
144         }\r
145
146         /* write the pixel the specified number of times */\r
147         for(; count && index < bufSize; count--,index++)  {\r
148                 result.data[index] = val;\r
149         }\r
150     } while(index < bufSize);\r
151 \r
152     loadPcxPalette(file, &result);\r
153 \r
154     fclose(file);\r
155 \r
156     return result;\r
157 }\r
158 \r
159 //update!!\r
160 tileset_t\r
161 bitmapLoadPcxTiles(char *filename, word twidth, word theight) {\r
162     tileset_t ts;\r
163     FILE *file;\r
164     bitmap_t result;\r
165     int i;\r
166 \r
167     /* open the PCX file for reading */\r
168     file = fopen(filename, "rb");\r
169         if(!file) {\r
170                 printf("Could not open %s for reading.\n", filename);\r
171                 exit(-2);\r
172         }\r
173 \r
174     /* load the first part of the pcx file */\r
175     loadPcxStage1(file, &result);\r
176 \r
177     /* get the number of tiles and set up the result structure */\r
178     ts.twidth = twidth;\r
179     ts.theight = theight;\r
180     ts.ntiles = (result.width/twidth) * (result.height/theight);\r
181     ts.palette = result.palette;\r
182 \r
183         /* allocate the pixel storage for the tiles */\r
184         ts.data = malloc(sizeof(byte*) * ts.ntiles);\r
185         ts.data[0] = malloc(sizeof(byte) * ts.ntiles * twidth * theight);\r
186         for(i=1; i < ts.ntiles; i++) {\r
187                 ts.data[i] = ts.data[i-1] + twidth * theight;\r
188         }\r
189 \r
190     /* finish off the file */\r
191     loadPcxPalette(file, &result);\r
192 \r
193     fclose(file);\r
194 \r
195     return ts;\r
196 }\r