Mercurial > otakunoraifu
annotate system/visarc.cc @ 71:1fd20d231376
Fix objScale with 2D zoom; implement objWidth and objHeight.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 01 Apr 2011 23:49:12 +0200 |
parents | 4416cfac86ae |
children |
rev | line source |
---|---|
0 | 1 #define CMDNAME "visarc" |
2 #define VERSION "1.00" | |
3 | |
4 /***************************************** | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
5 ** Visual Arts の圧縮書庫ファイルを |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
6 ** 展開する |
0 | 7 ** |
8 ** usage : visarc x <arcfile> <file> [<file> ...] | |
9 ** visarc l <arcfile> | |
10 ** visarc g <arcfile> <graphic file> | |
11 ** visarc m <arcfile> <mask file> | |
12 ** | |
13 ****************************************** | |
14 */ | |
15 /* | |
16 * | |
17 * Copyright (C) 2000- Kazunori Ueno(JAGARL) <jagarl@creator.club.ne.jp> | |
18 * | |
19 * This program is free software; you can redistribute it and/or modify | |
20 * it under the terms of the GNU General Public License as published by | |
21 * the Free Software Foundation; either version 2 of the License, or | |
22 * (at your option) any later version. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, | |
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27 * GNU General Public License for more details. | |
28 * | |
27 | 29 * You should have received a copy of the GNU General Public License along |
30 * with this program; if not, write to the Free Software Foundation, Inc., | |
31 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
0 | 32 * |
33 */ | |
34 | |
35 #ifdef HAVE_CONFIG_H | |
36 # include "config.h" | |
37 #endif | |
38 | |
39 #include <stdio.h> | |
40 #include <unistd.h> | |
41 #include <string.h> | |
42 | |
43 // use only file subsystem | |
44 #include "file.h" | |
45 #include "file_impl.h" | |
46 // #include "file.cc" | |
47 | |
48 #ifdef HAVE_LIBPNG | |
49 #include <png.h> | |
50 #endif | |
51 | |
52 void usage(void) { | |
53 fprintf(stderr, "usage : visarc <cmd> <arcfile> [<file1> [<file2> [...] ]]\n"); | |
54 fprintf(stderr, " cmd : x : extract\n"); | |
55 fprintf(stderr, " l : list all files\n"); | |
56 fprintf(stderr, "\n"); | |
57 #ifdef HAVE_LIBPNG | |
58 fprintf(stderr, "usage2: visarc <cmd> <pdt-file> [<output-file>]\n"); | |
59 fprintf(stderr, " cmd p : unpack pdt file and save as png file\n"); | |
60 #endif /* HAVE_LIBPNG */ | |
61 fprintf(stderr, "\n"); | |
62 } | |
63 | |
64 void List(char* path) { | |
65 ARCFILE* file; | |
66 FILE* f = fopen(path, "rb"); | |
52 | 67 if (f == NULL) return; |
0 | 68 char header[32]; |
69 fread(header, 32, 1, f); | |
70 fclose(f); | |
71 char magic_raf[8] = {'C','A','P','F',1,0,0,0}; | |
72 if (strncmp(header, "PACL", 4) == 0) file = new ARCFILE(path); | |
73 else file = new SCN2kFILE(path); | |
74 file->Init(); | |
75 file->ListFiles(stdout); | |
76 delete file; | |
77 } | |
78 | |
79 void ExtractOne(ARCFILE* arc, char* file) { | |
80 ARCINFO* info = arc->Find(file,""); | |
52 | 81 if (info == NULL) { |
0 | 82 fprintf(stderr, "Cannot find file %s in archive\n",file); |
83 return; | |
84 } | |
85 FILE* out = fopen(file, "w"); | |
52 | 86 if (out == NULL) { |
0 | 87 delete info; |
88 fprintf(stderr, "Cannot open output file %s\n",file); | |
89 return; | |
90 } | |
91 | |
92 fprintf(stdout, "Extracting %s ... ",file); | |
93 int size = info->Size(); | |
94 const char* data = info->Read(); | |
95 fwrite(data, size, 1, out); | |
96 fclose(out); | |
97 fprintf(stdout, "done\n"); | |
98 delete info; | |
99 } | |
100 | |
101 void Extract(char* path, char** files, int fnum) { | |
102 ARCFILE* file; | |
103 FILE* f = fopen(path, "rb"); | |
52 | 104 if (f == NULL) return; |
0 | 105 char header[32]; |
106 fread(header, 32, 1, f); | |
107 fclose(f); | |
108 char magic_raf[8] = {'C','A','P','F',1,0,0,0}; | |
109 if (strncmp(header, "PACL", 4) == 0) file = new ARCFILE(path); | |
110 else file = new SCN2kFILE(path); | |
111 file->Init(); | |
52 | 112 if (files != NULL && fnum != 0) { |
0 | 113 int i; for (i=0; i<fnum; i++) { |
114 ExtractOne(file, files[i]); | |
115 } | |
116 } else { | |
117 file->InitList(); | |
52 | 118 char* path; |
119 while( (path=file->ListItem()) != 0) { | |
0 | 120 ExtractOne(file, path); |
121 } | |
122 } | |
123 delete file; | |
124 } | |
125 | |
126 void ChangeExt(char* path, char* new_ext, char* buf) { | |
127 char* name = strrchr(path, DIR_SPLIT); | |
52 | 128 if (name == NULL) name = path; |
0 | 129 else name++; |
130 int path_len = name - path; | |
131 | |
132 char* ext = strrchr(name, '.'); | |
133 int ext_len; | |
134 if (ext) ext_len = ext - name; | |
135 else ext_len = strlen(name); | |
136 | |
137 strncpy(buf, path, path_len+ext_len); | |
138 strcpy(buf+path_len+ext_len, new_ext); | |
139 } | |
140 | |
141 char* ReadFile(char* fname, int* len) { | |
142 FILE* in = fopen(fname, "rb"); | |
52 | 143 if (in == NULL) return 0; |
144 fseek(in, 0, SEEK_END); | |
145 size_t s = ftell(in); | |
146 fseek(in, 0, SEEK_SET); | |
0 | 147 char* buf = new char[s]; |
148 fread(buf,s,1,in); | |
149 fclose(in); | |
150 if (len) *len = s; | |
151 return buf; | |
152 } | |
153 | |
154 | |
155 #ifdef HAVE_LIBPNG | |
156 void create_png(FILE* stream, char* path, char* desc, int width, int height, char* data) { | |
157 png_structp png_ptr; | |
158 png_infop info_ptr; | |
159 | |
160 /* create struct */ | |
161 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | |
162 if (png_ptr == NULL) return; | |
163 | |
164 /* initialize information */ | |
165 info_ptr = png_create_info_struct(png_ptr); | |
166 if (info_ptr == NULL) { | |
167 png_destroy_write_struct(&png_ptr, (png_infop*)NULL); | |
168 return; | |
169 } | |
170 | |
171 if (setjmp(png_jmpbuf(png_ptr))) { | |
172 /* error occured !! */ | |
173 png_destroy_write_struct(&png_ptr,&info_ptr); | |
174 fprintf(stderr, "Get error while processing PNG from file %s\n",path); | |
175 return; | |
176 } | |
177 | |
178 /* initialize I/O (for stream) */ | |
179 png_init_io(png_ptr, stream); | |
180 | |
181 /* initialize headers */ | |
182 png_set_IHDR(png_ptr, info_ptr, | |
183 width, height, 8 /* bit_dept */, | |
184 PNG_COLOR_TYPE_RGB_ALPHA, | |
185 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); | |
186 /* create text information */ | |
187 png_text info_text[3]; | |
188 info_text[0].key = "Title"; | |
189 info_text[0].text= path; | |
190 info_text[0].compression = PNG_TEXT_COMPRESSION_NONE; | |
191 info_text[1].key = "Author"; | |
192 info_text[1].text= CMDNAME " version " VERSION; | |
193 info_text[1].compression = PNG_TEXT_COMPRESSION_NONE; | |
194 info_text[2].key = "Description"; | |
195 info_text[2].text= desc; | |
196 info_text[2].compression = PNG_TEXT_COMPRESSION_NONE; | |
197 png_set_text(png_ptr, info_ptr, info_text, 3); | |
198 | |
199 /* write information */ | |
200 png_write_info(png_ptr, info_ptr); | |
201 | |
202 /* write body */ | |
203 /* rgba image ; input/output is 32bpp.*/ | |
204 char* row = new char[width*4]; | |
205 int i; for (i=0; i<height; i++) { | |
206 char* row_ptr = row; | |
207 int j; for (j=0; j<width; j++) { | |
208 row_ptr[0] = data[2]; | |
209 row_ptr[1] = data[1]; | |
210 row_ptr[2] = data[0]; | |
211 row_ptr[3] = data[3]; | |
212 row_ptr += 4; data += 4; | |
213 } | |
214 png_write_rows(png_ptr, (png_byte**)&row, 1); | |
215 } | |
216 png_write_end(png_ptr, info_ptr); | |
217 png_destroy_write_struct(&png_ptr, &info_ptr); | |
218 } | |
219 | |
220 void ExtractPngRgbaGraphic(char* path,char* outpath = 0) { | |
221 char buf[1024]; char* fname = buf; | |
222 int len; | |
223 char* dat = ReadFile(path, &len); | |
52 | 224 if (dat == NULL) { |
0 | 225 fprintf(stderr, "Cannot open PDT file : %s\n",path); |
226 return; | |
227 } | |
228 GRPCONV* conv = GRPCONV::AssignConverter(dat, len, path); | |
52 | 229 if (conv == NULL) { |
0 | 230 fprintf(stderr, "Invalid format\n"); |
231 return; | |
232 } | |
233 bool masked = conv->IsMask(); | |
234 char* data = new char[conv->Width() * conv->Height() * 4 + 1024]; | |
235 if (! conv->Read(data)) { | |
236 fprintf(stderr, "Insufficient memory\n"); | |
237 delete conv; | |
238 return; | |
239 } | |
240 if (! masked) { | |
241 for (int i = 0; i < conv->Width() * conv->Height(); i++) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
242 data[4*i+3] = 0xff; // 不透明度を最大にする |
0 | 243 } |
244 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
245 if (outpath == NULL) ChangeExt(path,".png", buf); // path をつくる |
0 | 246 else fname = outpath; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
247 FILE* out = fopen(fname, "wb"); // ファイルを開く |
52 | 248 if (out == NULL) { |
0 | 249 fprintf(stderr, "Cannot open raw file : %s\n",buf); |
250 delete conv; | |
251 return; | |
252 } | |
253 create_png(out, path, "", conv->Width(), conv->Height(), data); | |
254 fclose(out); | |
255 | |
256 delete conv; | |
257 } | |
258 #endif /* HAVE_LIBPNG */ | |
259 | |
260 int main(int argc, char* argv[]) { | |
261 int i; | |
262 fprintf(stderr, "%s version %s\n", CMDNAME, VERSION); | |
263 if (argc < 3) { | |
264 usage(); return -1; | |
265 } | |
266 if (strlen(argv[1]) != 1) { | |
267 usage(); return -1; | |
268 } | |
269 for (i=2; i<argc; i++) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
270 /* option を削る */ |
0 | 271 argc--; |
272 int j; for (j=i; j<argc; j++) argv[j] = argv[j+1]; | |
273 } | |
274 switch(argv[1][0]) { | |
275 case 'x': case 'X': | |
276 if (argc < 4) Extract(argv[2], 0, -1); | |
277 else Extract(argv[2], argv+3, argc-3); | |
278 break; | |
279 case 'l': case 'L': | |
280 List(argv[2]); | |
281 break; | |
282 #ifdef HAVE_LIBPNG | |
283 case 'p': case 'P': | |
284 case 'a': case 'A': | |
285 if (argc < 4) | |
286 ExtractPngRgbaGraphic(argv[2]); | |
287 else | |
288 ExtractPngRgbaGraphic(argv[2],argv[3]); | |
289 break; | |
290 #endif /* HAVE_LIBPNG */ | |
291 default: | |
292 usage(); return -1; | |
293 } | |
294 return 0; | |
295 } |