Revision | 137 (tree) |
---|---|
Time | 2008-08-19 13:13:36 |
Author | bird_may_nike |
(empty log message)
@@ -0,0 +1,840 @@ | ||
1 | +/* | |
2 | +* $Id$ | |
3 | +*/ | |
4 | + | |
5 | +#include <stdio.h> | |
6 | +#include <malloc.h> | |
7 | +#include <jpeglib.h> | |
8 | +#include <png.h> | |
9 | +#include "giflib/gif_lib.h" | |
10 | +#include "psp2ch.h" | |
11 | +#include "pg.h" | |
12 | +#include "psp2chImageView.h" | |
13 | + | |
14 | +extern S_2CH s2ch; //psp2ch.c | |
15 | +extern unsigned int list[BUF_WIDTH*BUF_HEIGHT]; // pg.c | |
16 | +extern unsigned int pixels[BUF_WIDTH*BUF_HEIGHT]; // pg.c | |
17 | +extern int preLine; // psp2chRes.c | |
18 | + | |
19 | +/***************************** | |
20 | +jpegファイルを読み込んで32ビットRGBAに変換 | |
21 | +*****************************/ | |
22 | +int psp2chImageViewJpeg(char* fname) | |
23 | +{ | |
24 | + FILE* infile; | |
25 | + JSAMPARRAY img; | |
26 | + JSAMPROW buf, imgbuf, tmp; | |
27 | + int width; | |
28 | + int height; | |
29 | + int i; | |
30 | + struct jpeg_decompress_struct cinfo; | |
31 | + struct jpeg_error_mgr jerr; | |
32 | + unsigned char header[4]; | |
33 | + | |
34 | + infile = fopen(fname, "rb" ); | |
35 | + if (!infile) | |
36 | + { | |
37 | + return -1; | |
38 | + } | |
39 | + // 一応ヘッダのチェック | |
40 | + fread(header, 1, 2, infile); | |
41 | + fseek(infile, 0, SEEK_SET); | |
42 | + if (header[0] != 0xFF || header[1] != 0xD8) | |
43 | + { | |
44 | + fclose(infile); | |
45 | + return -1; | |
46 | + } | |
47 | + cinfo.err = jpeg_std_error(&jerr); | |
48 | + jpeg_create_decompress(&cinfo); | |
49 | + jpeg_stdio_src(&cinfo, infile); | |
50 | + jpeg_read_header(&cinfo, TRUE); | |
51 | + jpeg_start_decompress(&cinfo); | |
52 | + width = cinfo.output_width; | |
53 | + height = cinfo.output_height; | |
54 | + img = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * height); | |
55 | + if (!img) | |
56 | + { | |
57 | + fclose(infile); | |
58 | + return -1; | |
59 | + } | |
60 | + imgbuf = (JSAMPROW)calloc(sizeof(JSAMPLE), 4 * width * height); | |
61 | + if (!imgbuf) | |
62 | + { | |
63 | + free(img); | |
64 | + fclose(infile); | |
65 | + return -1; | |
66 | + } | |
67 | + buf = (JSAMPROW)calloc(sizeof(JSAMPLE), 3 * width); | |
68 | + if (!buf) | |
69 | + { | |
70 | + free(imgbuf); | |
71 | + free(img); | |
72 | + fclose(infile); | |
73 | + return -1; | |
74 | + } | |
75 | + tmp = imgbuf; | |
76 | + for (i = 0; i < height; i++ ) | |
77 | + { | |
78 | + img[i] = &tmp[i * width * 4]; | |
79 | + } | |
80 | + // RGBカラーをRGBAに | |
81 | + if (cinfo.out_color_components == 3) | |
82 | + { | |
83 | + while(cinfo.output_scanline < cinfo.output_height) | |
84 | + { | |
85 | + jpeg_read_scanlines(&cinfo, &buf, 1); | |
86 | + for (i = 0; i < width; i++) | |
87 | + { | |
88 | + img[cinfo.output_scanline-1][i * 4 + 0] = buf[i * 3 + 0]; | |
89 | + img[cinfo.output_scanline-1][i * 4 + 1] = buf[i * 3 + 1]; | |
90 | + img[cinfo.output_scanline-1][i * 4 + 2] = buf[i * 3 + 2]; | |
91 | + img[cinfo.output_scanline-1][i * 4 + 3] = 0xFF; | |
92 | + } | |
93 | + } | |
94 | + } | |
95 | + // グレースケールをRGBAに | |
96 | + else if (cinfo.out_color_components == 1) | |
97 | + { | |
98 | + while(cinfo.output_scanline < cinfo.output_height) | |
99 | + { | |
100 | + jpeg_read_scanlines(&cinfo, &buf, 1); | |
101 | + for (i = 0; i < width; i++) | |
102 | + { | |
103 | + img[cinfo.output_scanline-1][i * 4 + 0] = buf[i]; | |
104 | + img[cinfo.output_scanline-1][i * 4 + 1] = buf[i]; | |
105 | + img[cinfo.output_scanline-1][i * 4 + 2] = buf[i]; | |
106 | + img[cinfo.output_scanline-1][i * 4 + 3] = 0xFF; | |
107 | + } | |
108 | + } | |
109 | + } | |
110 | + else | |
111 | + { | |
112 | + free(buf); | |
113 | + free(imgbuf); | |
114 | + free(img); | |
115 | + jpeg_destroy_decompress(&cinfo); | |
116 | + fclose(infile); | |
117 | + return -1; | |
118 | + } | |
119 | + free(buf); | |
120 | + jpeg_finish_decompress(&cinfo); | |
121 | + jpeg_destroy_decompress(&cinfo); | |
122 | + fclose(infile); | |
123 | + psp2chImageViewer((int**)img, width, height, fname); | |
124 | + free(imgbuf); | |
125 | + free(img); | |
126 | + preLine = -2; | |
127 | + return 0; | |
128 | +} | |
129 | + | |
130 | +/***************************** | |
131 | +PNGファイルを読み込んで32ビットRGBAに変換 | |
132 | +*****************************/ | |
133 | +int psp2chImageViewPng(char* fname) | |
134 | +{ | |
135 | + FILE* infile; | |
136 | + png_structp png_ptr; | |
137 | + png_infop info_ptr; | |
138 | + png_infop end_info; | |
139 | + unsigned long width, height; | |
140 | + int bit_depth, color_type, interlace_type; | |
141 | + png_bytepp img; | |
142 | + png_bytep imgbuf; | |
143 | + int i; | |
144 | + unsigned char header[8]; | |
145 | + | |
146 | + infile = fopen(fname, "rb"); | |
147 | + if (!infile) | |
148 | + { | |
149 | + return -1; | |
150 | + } | |
151 | + fread(header, 1, 8, infile); | |
152 | + // PNGチェック | |
153 | + if (png_sig_cmp(header, 0, 8)) | |
154 | + { | |
155 | + fclose(infile); | |
156 | + return -1; | |
157 | + } | |
158 | + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | |
159 | + info_ptr = png_create_info_struct(png_ptr); | |
160 | + end_info = png_create_info_struct(png_ptr); | |
161 | + if (setjmp(png_jmpbuf(png_ptr))) | |
162 | + { | |
163 | + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); | |
164 | + fclose(infile); | |
165 | + return -1; | |
166 | + } | |
167 | + png_init_io(png_ptr, infile); | |
168 | + png_set_sig_bytes(png_ptr, 8); | |
169 | + png_read_info(png_ptr, info_ptr); | |
170 | + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); | |
171 | + //パレット系->RGB系に拡張 | |
172 | + if (color_type == PNG_COLOR_TYPE_PALETTE || | |
173 | + (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) || | |
174 | + png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) | |
175 | + { | |
176 | + png_set_expand(png_ptr); | |
177 | + } | |
178 | + //16ビット->8ビットに落とす | |
179 | + if (bit_depth == 16) | |
180 | + { | |
181 | + png_set_strip_16(png_ptr); | |
182 | + } | |
183 | + //グレースケール->RGBに拡張 | |
184 | + if (color_type==PNG_COLOR_TYPE_GRAY || | |
185 | + color_type==PNG_COLOR_TYPE_GRAY_ALPHA) | |
186 | + { | |
187 | + png_set_gray_to_rgb(png_ptr); | |
188 | + } | |
189 | + if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) | |
190 | + { | |
191 | + png_set_add_alpha(png_ptr, 0xFFFF, PNG_FILLER_AFTER); | |
192 | + } | |
193 | + png_read_update_info(png_ptr, info_ptr); | |
194 | + img = (png_bytepp)malloc(height * sizeof(png_bytep)); | |
195 | + if (!img) | |
196 | + { | |
197 | + fclose(infile); | |
198 | + return -1; | |
199 | + } | |
200 | + imgbuf = (png_bytep)malloc(png_get_rowbytes(png_ptr, info_ptr) * width); | |
201 | + if (!imgbuf) | |
202 | + { | |
203 | + free(img); | |
204 | + fclose(infile); | |
205 | + return -1; | |
206 | + } | |
207 | + for (i = 0; i < height; i++) | |
208 | + { | |
209 | + img[i] = &imgbuf[i * width * 4]; | |
210 | + } | |
211 | + png_read_image(png_ptr, img); | |
212 | + png_read_end(png_ptr, end_info); | |
213 | + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); | |
214 | + fclose(infile); | |
215 | + psp2chImageViewer((int**)img, (int)width, (int)height, fname); | |
216 | + free(imgbuf); | |
217 | + free(img); | |
218 | + preLine = -2; | |
219 | + return 0; | |
220 | +} | |
221 | + | |
222 | +/***************************** | |
223 | +BMPファイルを読み込んで32ビットRGBAに変換 | |
224 | +*****************************/ | |
225 | +int psp2chImageViewBmp(char* fname) | |
226 | +{ | |
227 | + FILE* infile; | |
228 | + int i, j, y, height, len; | |
229 | + BITMAPFILEHEADER bf; | |
230 | + BITMAPINFOHEADER bi; | |
231 | + unsigned char **img, *imgbuf, *buf, *tmp; | |
232 | + | |
233 | + infile = fopen(fname, "rb" ); | |
234 | + if (!infile) | |
235 | + { | |
236 | + return -1; | |
237 | + } | |
238 | + if (fread(&bf, sizeof(BITMAPFILEHEADER), 1, infile) != 1) | |
239 | + { | |
240 | + fclose(infile); | |
241 | + return -1; | |
242 | + } | |
243 | + // BITMAP 認識文字 "BM" | |
244 | + if (memcmp(bf.bfType, "BM", 2) != 0) | |
245 | + { | |
246 | + fclose(infile); | |
247 | + return -1; | |
248 | + } | |
249 | + if (fread(&bi, sizeof(BITMAPINFOHEADER), 1, infile) != 1) | |
250 | + { | |
251 | + fclose(infile); | |
252 | + return -1; | |
253 | + } | |
254 | + // 非圧縮のみ | |
255 | + if (bi.biCompression) | |
256 | + { | |
257 | + fclose(infile); | |
258 | + return -1; | |
259 | + } | |
260 | + if (bi.biHeight < 0) | |
261 | + { | |
262 | + height = -bi.biHeight; | |
263 | + } | |
264 | + else | |
265 | + { | |
266 | + height = bi.biHeight; | |
267 | + } | |
268 | + img = (unsigned char**)malloc(sizeof(unsigned char*) * height); | |
269 | + if (!img) | |
270 | + { | |
271 | + fclose(infile); | |
272 | + return -1; | |
273 | + } | |
274 | + imgbuf = (unsigned char*)calloc(sizeof(unsigned char), 4 * bi.biWidth * height); | |
275 | + if (!imgbuf) | |
276 | + { | |
277 | + free(img); | |
278 | + fclose(infile); | |
279 | + return -1; | |
280 | + } | |
281 | + len = bi.biWidth * bi.biBitCount / 8; | |
282 | + len += (4 - (len & 3)) & 3; | |
283 | + buf = (unsigned char*)calloc(sizeof(unsigned char), len); | |
284 | + if (!buf) | |
285 | + { | |
286 | + free(imgbuf); | |
287 | + free(img); | |
288 | + fclose(infile); | |
289 | + return -1; | |
290 | + } | |
291 | + tmp = imgbuf; | |
292 | + for (i = 0; i < height; i++ ) | |
293 | + { | |
294 | + img[i] = &tmp[i * bi.biWidth * 4]; | |
295 | + } | |
296 | + fseek(infile, bf.bfOffBits, SEEK_SET); | |
297 | + // 24ビットBMPをRGBAに | |
298 | + if (bi.biBitCount == 24) | |
299 | + { | |
300 | + for (j = 0; j < height; j++) | |
301 | + { | |
302 | + if (bi.biHeight < 0) | |
303 | + { | |
304 | + y = j; | |
305 | + } | |
306 | + else | |
307 | + { | |
308 | + y = height - j - 1; | |
309 | + } | |
310 | + fread(buf, 1, len, infile); | |
311 | + for (i = 0; i < bi.biWidth; i++) | |
312 | + { | |
313 | + img[y][i * 4 + 0] = buf[i * 3 + 2]; | |
314 | + img[y][i * 4 + 1] = buf[i * 3 + 1]; | |
315 | + img[y][i * 4 + 2] = buf[i * 3 + 0]; | |
316 | + img[y][i * 4 + 3] = 0xFF; | |
317 | + } | |
318 | + } | |
319 | + } | |
320 | + // 32ビットBMPをRGBAに | |
321 | + else if (bi.biBitCount == 32) | |
322 | + { | |
323 | + for (j = 0; j <height; j++) | |
324 | + { | |
325 | + if (bi.biHeight < 0) | |
326 | + { | |
327 | + y = j; | |
328 | + } | |
329 | + else | |
330 | + { | |
331 | + y = height - j - 1; | |
332 | + } | |
333 | + fread(buf, 1, len, infile); | |
334 | + for (i = 0; i < bi.biWidth; i++) | |
335 | + { | |
336 | + img[y][i * 4 + 0] = buf[i * 4 + 2]; | |
337 | + img[y][i * 4 + 1] = buf[i * 4 + 1]; | |
338 | + img[y][i * 4 + 2] = buf[i * 4 + 0]; | |
339 | + img[y][i * 4 + 3] = 0xFF; | |
340 | + } | |
341 | + } | |
342 | + } | |
343 | + // 未対応 | |
344 | + else | |
345 | + { | |
346 | + free(buf); | |
347 | + free(imgbuf); | |
348 | + free(img); | |
349 | + fclose(infile); | |
350 | + return -1; | |
351 | + } | |
352 | + free(buf); | |
353 | + fclose(infile); | |
354 | + psp2chImageViewer((int**)img, bi.biWidth, height, fname); | |
355 | + free(imgbuf); | |
356 | + free(img); | |
357 | + preLine = -2; | |
358 | + return 0; | |
359 | +} | |
360 | + | |
361 | +/***************************** | |
362 | +GIFファイルを読み込んで32ビットRGBAに変換 | |
363 | +*****************************/ | |
364 | +int psp2chImageViewGif(char* fname) | |
365 | +{ | |
366 | + int InterlacedOffset[] = { 0, 4, 2, 1 }; /* The way Interlaced image should. */ | |
367 | + int InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ | |
368 | + int i, j, Size, Row, Col, Width, Height, Count, ExtCode; | |
369 | + GifFileType *GifFile; | |
370 | + GifRowType *ScreenBuffer, ImgBuf, GifRow; | |
371 | + GifRecordType RecordType; | |
372 | + GifByteType *Extension; | |
373 | + GifColorType *ColorMapEntry; | |
374 | + ColorMapObject *ColorMap; | |
375 | + unsigned char **img, *buf, *BufferP; | |
376 | + | |
377 | + if ((GifFile = DGifOpenFileName(fname)) == NULL) | |
378 | + { | |
379 | + return -1; | |
380 | + } | |
381 | + if ((ScreenBuffer = (GifRowType *)malloc(GifFile->SHeight * sizeof(GifRowType *))) == NULL) | |
382 | + { | |
383 | + DGifCloseFile(GifFile); | |
384 | + return -1; | |
385 | + } | |
386 | + Size = GifFile->SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ | |
387 | + if ((ImgBuf = (GifRowType)malloc(Size * GifFile->SHeight)) == NULL) | |
388 | + { | |
389 | + free(ScreenBuffer); | |
390 | + DGifCloseFile(GifFile); | |
391 | + return -1; | |
392 | + } | |
393 | + if ((img = (unsigned char**)malloc(sizeof(unsigned char*) * GifFile->SHeight)) == NULL) | |
394 | + { | |
395 | + free(ImgBuf); | |
396 | + free(ScreenBuffer); | |
397 | + DGifCloseFile(GifFile); | |
398 | + return -1; | |
399 | + } | |
400 | + if ((buf = (unsigned char*)malloc(4 * GifFile->SWidth * GifFile->SHeight)) == NULL) | |
401 | + { | |
402 | + free(img); | |
403 | + free(ImgBuf); | |
404 | + free(ScreenBuffer); | |
405 | + DGifCloseFile(GifFile); | |
406 | + return -1; | |
407 | + } | |
408 | + for (i = 0; i < GifFile->SHeight; i++) | |
409 | + { | |
410 | + ScreenBuffer[i] = &ImgBuf[i * Size]; | |
411 | + img[i] = &buf[i * 4 * GifFile->SWidth]; | |
412 | + } | |
413 | + for (i = 0; i < GifFile->SWidth; i++) /* Set its color to BackGround. */ | |
414 | + { | |
415 | + ScreenBuffer[0][i] = GifFile->SBackGroundColor; | |
416 | + } | |
417 | + for (i = 1; i < GifFile->SHeight; i++) | |
418 | + { | |
419 | + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); | |
420 | + } | |
421 | + /* Scan the content of the GIF file and load the image(s) in: */ | |
422 | + do | |
423 | + { | |
424 | + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) | |
425 | + { | |
426 | + free(buf); | |
427 | + free(img); | |
428 | + free(ImgBuf); | |
429 | + free(ScreenBuffer); | |
430 | + DGifCloseFile(GifFile); | |
431 | + return -1; | |
432 | + } | |
433 | + switch (RecordType) | |
434 | + { | |
435 | + case IMAGE_DESC_RECORD_TYPE: | |
436 | + if (DGifGetImageDesc(GifFile) == GIF_ERROR) | |
437 | + { | |
438 | + free(buf); | |
439 | + free(img); | |
440 | + free(ImgBuf); | |
441 | + free(ScreenBuffer); | |
442 | + DGifCloseFile(GifFile); | |
443 | + return -1; | |
444 | + } | |
445 | + Row = GifFile->Image.Top; /* Image Position relative to Screen. */ | |
446 | + Col = GifFile->Image.Left; | |
447 | + Width = GifFile->Image.Width; | |
448 | + Height = GifFile->Image.Height; | |
449 | + if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth || | |
450 | + GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) | |
451 | + { | |
452 | + free(buf); | |
453 | + free(img); | |
454 | + free(ImgBuf); | |
455 | + free(ScreenBuffer); | |
456 | + DGifCloseFile(GifFile); | |
457 | + return -1; | |
458 | + } | |
459 | + if (GifFile->Image.Interlace) { | |
460 | + /* Need to perform 4 passes on the images: */ | |
461 | + for (Count = i = 0; i < 4; i++) | |
462 | + { | |
463 | + for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) | |
464 | + { | |
465 | + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], Width) == GIF_ERROR) | |
466 | + { | |
467 | + free(buf); | |
468 | + free(img); | |
469 | + free(ImgBuf); | |
470 | + free(ScreenBuffer); | |
471 | + DGifCloseFile(GifFile); | |
472 | + return -1; | |
473 | + } | |
474 | + } | |
475 | + } | |
476 | + } | |
477 | + else { | |
478 | + for (i = 0; i < Height; i++) | |
479 | + { | |
480 | + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], Width) == GIF_ERROR) | |
481 | + { | |
482 | + free(buf); | |
483 | + free(img); | |
484 | + free(ImgBuf); | |
485 | + free(ScreenBuffer); | |
486 | + DGifCloseFile(GifFile); | |
487 | + return -1; | |
488 | + } | |
489 | + } | |
490 | + } | |
491 | + break; | |
492 | + case EXTENSION_RECORD_TYPE: | |
493 | + /* Skip any extension blocks in file: */ | |
494 | + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) | |
495 | + { | |
496 | + free(buf); | |
497 | + free(img); | |
498 | + free(ImgBuf); | |
499 | + free(ScreenBuffer); | |
500 | + DGifCloseFile(GifFile); | |
501 | + return -1; | |
502 | + } | |
503 | + while (Extension != NULL) | |
504 | + { | |
505 | + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) | |
506 | + { | |
507 | + free(buf); | |
508 | + free(img); | |
509 | + free(ImgBuf); | |
510 | + free(ScreenBuffer); | |
511 | + DGifCloseFile(GifFile); | |
512 | + return -1; | |
513 | + } | |
514 | + } | |
515 | + break; | |
516 | + case TERMINATE_RECORD_TYPE: | |
517 | + break; | |
518 | + default: /* Should be traps by DGifGetRecordType. */ | |
519 | + break; | |
520 | + } | |
521 | + } while (RecordType != TERMINATE_RECORD_TYPE); | |
522 | + ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap); | |
523 | + if (ColorMap == NULL) | |
524 | + { | |
525 | + free(buf); | |
526 | + free(img); | |
527 | + free(ImgBuf); | |
528 | + free(ScreenBuffer); | |
529 | + DGifCloseFile(GifFile); | |
530 | + return -1; | |
531 | + } | |
532 | + for (i = 0; i < GifFile->SHeight; i++) { | |
533 | + GifRow = ScreenBuffer[i]; | |
534 | + BufferP = img[i]; | |
535 | + for (j = 0; j < GifFile->SWidth; j++) { | |
536 | + ColorMapEntry = &ColorMap->Colors[GifRow[j]]; | |
537 | + *BufferP++ = ColorMapEntry->Red; | |
538 | + *BufferP++ = ColorMapEntry->Green; | |
539 | + *BufferP++ = ColorMapEntry->Blue; | |
540 | + *BufferP++ = 0xFF; | |
541 | + } | |
542 | + } | |
543 | + psp2chImageViewer((int**)img, GifFile->SWidth, GifFile->SHeight, fname); | |
544 | + DGifCloseFile(GifFile); | |
545 | + free(buf); | |
546 | + free(img); | |
547 | + free(ImgBuf); | |
548 | + free(ScreenBuffer); | |
549 | + preLine = -2; | |
550 | + return 0; | |
551 | +} | |
552 | + | |
553 | +/*-------------------------------------------------------- | |
554 | + 矩形範囲を拡大縮小 | |
555 | +--------------------------------------------------------*/ | |
556 | +#define SLICE_SIZE 64 | |
557 | +void blt(void *src, TEX *tex, int sw, int sh, int dw, int dh) | |
558 | +{ | |
559 | + int i, j, dy; | |
560 | + struct Vertex *vertices; | |
561 | + int* p = src; | |
562 | + | |
563 | + dy = BUF_HEIGHT * dw / sw; | |
564 | + | |
565 | + sceGuStart(GU_DIRECT, list); | |
566 | + sceGuDrawBufferList(GU_PSM_8888, framebuffer, BUF_WIDTH); | |
567 | + sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); | |
568 | + sceGuClearColor(GU_RGBA(128,128,128,255)); | |
569 | + sceGuClear(GU_COLOR_BUFFER_BIT); | |
570 | + sceGuTexMode(GU_PSM_8888, 0, 0, GU_FALSE); | |
571 | + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); | |
572 | + sceGuTexWrap(GU_CLAMP, GU_CLAMP); | |
573 | + if (sw == dw) | |
574 | + sceGuTexFilter(GU_NEAREST, GU_NEAREST); | |
575 | + else | |
576 | + sceGuTexFilter(GU_LINEAR, GU_LINEAR); | |
577 | + i = 0; | |
578 | + /* textureをSLICE_SIZE * BUF_HEIGHTに切り取ってループ */ | |
579 | + while (sh > BUF_HEIGHT) | |
580 | + { | |
581 | + for (j = 0; (j + SLICE_SIZE) < sw; j = j + SLICE_SIZE) | |
582 | + { | |
583 | + sceGuTexImage(0, tex->w, tex->h, tex->tb, p + j); | |
584 | + vertices = (struct Vertex *)sceGuGetMemory(2 * sizeof(struct Vertex)); | |
585 | + vertices[0].u = 0; | |
586 | + vertices[0].v = 0; | |
587 | + vertices[0].x = j * dw / sw; | |
588 | + vertices[0].y = dy * i; | |
589 | + vertices[1].u = SLICE_SIZE; | |
590 | + vertices[1].v = BUF_HEIGHT; | |
591 | + vertices[1].x = (j + SLICE_SIZE) * dw / sw; | |
592 | + vertices[1].y = dy * (i + 1); | |
593 | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, vertices); | |
594 | + } | |
595 | + if (j < sw) | |
596 | + { | |
597 | + sceGuTexImage(0, tex->w, tex->h, tex->tb, p + j); | |
598 | + vertices = (struct Vertex *)sceGuGetMemory(2 * sizeof(struct Vertex)); | |
599 | + vertices[0].u = 0; | |
600 | + vertices[0].v = 0; | |
601 | + vertices[0].x = j * dw / sw; | |
602 | + vertices[0].y = dy * i; | |
603 | + vertices[1].u = sw - j; | |
604 | + vertices[1].v = BUF_HEIGHT; | |
605 | + vertices[1].x = dw; | |
606 | + vertices[1].y = dy * (i + 1); | |
607 | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, vertices); | |
608 | + } | |
609 | + sh -= BUF_HEIGHT; | |
610 | + p += tex->tb * BUF_HEIGHT; | |
611 | + i++; | |
612 | + } | |
613 | + for (j = 0; (j + SLICE_SIZE) < sw; j = j + SLICE_SIZE) | |
614 | + { | |
615 | + sceGuTexImage(0, tex->w, tex->h, tex->tb, p + j); | |
616 | + vertices = (struct Vertex *)sceGuGetMemory(2 * sizeof(struct Vertex)); | |
617 | + vertices[0].u = 0; | |
618 | + vertices[0].v = 0; | |
619 | + vertices[0].x = j * dw / sw; | |
620 | + vertices[0].y = dy * i; | |
621 | + vertices[1].u = SLICE_SIZE; | |
622 | + vertices[1].v = sh; | |
623 | + vertices[1].x = (j + SLICE_SIZE) * dw / sw; | |
624 | + vertices[1].y = dh; | |
625 | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, vertices); | |
626 | + } | |
627 | + if (j < sw) | |
628 | + { | |
629 | + sceGuTexImage(0, tex->w, tex->h, tex->tb, p + j); | |
630 | + vertices = (struct Vertex *)sceGuGetMemory(2 * sizeof(struct Vertex)); | |
631 | + vertices[0].u = 0; | |
632 | + vertices[0].v = 0; | |
633 | + vertices[0].x = j * dw / sw; | |
634 | + vertices[0].y = dy * i; | |
635 | + vertices[1].u = sw - j; | |
636 | + vertices[1].v = sh; | |
637 | + vertices[1].x = dw; | |
638 | + vertices[1].y = dh; | |
639 | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, vertices); | |
640 | + } | |
641 | + sceGuFinish(); | |
642 | + sceGuSync(0, GU_SYNC_FINISH); | |
643 | +} | |
644 | + | |
645 | +/***************************** | |
646 | +メニュー処理 | |
647 | +RGBAデータをVRAMに転送 | |
648 | +*****************************/ | |
649 | +void psp2chImageViewer(int* img[], int width, int height, char* fname) | |
650 | +{ | |
651 | + SceCtrlData pad; | |
652 | + SceCtrlData oldPad; | |
653 | + SceUID src, dst; | |
654 | + int padX, padY; | |
655 | + int ret, menu = 1, rMenu = 0; | |
656 | + char picturePath[256], buf[256]; | |
657 | + char *p; | |
658 | + double thumb, thumbW, thumbH; | |
659 | + int thumbFlag = 0; | |
660 | + int imgWH, imgHW, startX, startY, width2, height2, sx, sy; | |
661 | + TEX tex; | |
662 | + | |
663 | + startX = 0; | |
664 | + startY = 0; | |
665 | + width2 = width; | |
666 | + height2 = height; | |
667 | + thumb = 1.0; | |
668 | + thumbW = (double)width / SCR_WIDTH; | |
669 | + imgWH = height / thumbW; | |
670 | + thumbH = (double)height / SCR_HEIGHT; | |
671 | + imgHW = width / thumbH; | |
672 | + sceCtrlPeekBufferPositive(&oldPad, 1); | |
673 | + while (s2ch.running) | |
674 | + { | |
675 | + if(sceCtrlPeekBufferPositive(&pad, 1)) | |
676 | + { | |
677 | + if(pad.Buttons & PSP_CTRL_RTRIGGER) | |
678 | + { | |
679 | + rMenu = 1; | |
680 | + } | |
681 | + else | |
682 | + { | |
683 | + rMenu = 0; | |
684 | + } | |
685 | + if (pad.Buttons != oldPad.Buttons) | |
686 | + { | |
687 | + oldPad = pad; | |
688 | + if (rMenu) | |
689 | + { | |
690 | + if(pad.Buttons & PSP_CTRL_CIRCLE) | |
691 | + { | |
692 | + if (s2ch.cfg.imageDir[0]) | |
693 | + { | |
694 | + sprintf(picturePath, "ms0:/PICTURE/%s", s2ch.cfg.imageDir); | |
695 | + src = sceIoDopen(picturePath); | |
696 | + if (src < 0) | |
697 | + { | |
698 | + ret = sceIoMkdir(picturePath, 0777); | |
699 | + if (ret < 0) | |
700 | + { | |
701 | + continue; | |
702 | + } | |
703 | + } | |
704 | + else | |
705 | + { | |
706 | + sceIoDclose(src); | |
707 | + } | |
708 | + } | |
709 | + else | |
710 | + { | |
711 | + strcpy(picturePath, "ms0:/PICTURE"); | |
712 | + } | |
713 | + p = strrchr(fname, '/'); | |
714 | + if (p == NULL) | |
715 | + { | |
716 | + continue; | |
717 | + } | |
718 | + strcat(picturePath, p); | |
719 | + src = sceIoOpen(fname, PSP_O_RDONLY, 0777); | |
720 | + if (src < 0) | |
721 | + { | |
722 | + continue; | |
723 | + } | |
724 | + dst = sceIoOpen(picturePath, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_APPEND, 0777); | |
725 | + if (dst < 0) | |
726 | + { | |
727 | + continue; | |
728 | + } | |
729 | + while((ret = sceIoRead(src, buf, 256))) | |
730 | + { | |
731 | + sceIoWrite(dst, buf, ret); | |
732 | + } | |
733 | + sceIoClose(dst); | |
734 | + sceIoClose(src); | |
735 | + } | |
736 | + pgPrintMenuBar(" ○ : PICTUREフォルダへコピー "); | |
737 | + } | |
738 | + else | |
739 | + { | |
740 | + if(pad.Buttons & PSP_CTRL_CIRCLE) | |
741 | + { | |
742 | + thumbFlag++; | |
743 | + if (thumbFlag > 2) | |
744 | + { | |
745 | + thumbFlag = 0; | |
746 | + } | |
747 | + if (thumbFlag == 1) | |
748 | + { | |
749 | + thumb = thumbW; | |
750 | + width2 = SCR_WIDTH; | |
751 | + height2 = imgWH; | |
752 | + } | |
753 | + else if (thumbFlag == 2) | |
754 | + { | |
755 | + thumb = thumbH; | |
756 | + width2 = imgHW; | |
757 | + height2 = SCR_HEIGHT; | |
758 | + } | |
759 | + else | |
760 | + { | |
761 | + thumb = 1.0; | |
762 | + width2 = width; | |
763 | + height2 = height; | |
764 | + } | |
765 | + startX = 0; | |
766 | + startY = 0; | |
767 | + } | |
768 | + else if(pad.Buttons & PSP_CTRL_CROSS) | |
769 | + { | |
770 | + break; | |
771 | + } | |
772 | + else if(pad.Buttons & PSP_CTRL_TRIANGLE) | |
773 | + { | |
774 | + menu = menu ? 0 : 1; | |
775 | + } | |
776 | + else if(pad.Buttons & PSP_CTRL_SQUARE) | |
777 | + { | |
778 | + sceIoRemove(fname); | |
779 | + break; | |
780 | + } | |
781 | + } | |
782 | + pgPrintMenuBar(" ○ : 拡大縮小 × : 戻る △ : メニューオン・オフ □ : 削除"); | |
783 | + } | |
784 | + if(pad.Buttons & PSP_CTRL_UP) | |
785 | + { | |
786 | + startY -= 2; | |
787 | + } | |
788 | + if(pad.Buttons & PSP_CTRL_DOWN) | |
789 | + { | |
790 | + startY += 2; | |
791 | + } | |
792 | + if(pad.Buttons & PSP_CTRL_LEFT) | |
793 | + { | |
794 | + startX -= 2; | |
795 | + } | |
796 | + if(pad.Buttons & PSP_CTRL_RIGHT) | |
797 | + { | |
798 | + startX += 2; | |
799 | + } | |
800 | + padX = pad.Lx - 127; | |
801 | + padY = pad.Ly - 127; | |
802 | + if ((padX < -s2ch.cfg.padCutoff) || (padX > s2ch.cfg.padCutoff)) | |
803 | + { | |
804 | + startX += (padX)/4; | |
805 | + } | |
806 | + if ((padY < -s2ch.cfg.padCutoff) || (padY > s2ch.cfg.padCutoff)) | |
807 | + { | |
808 | + startY += (padY)/4; | |
809 | + } | |
810 | + } | |
811 | + if (startX >= width2 - SCR_WIDTH) | |
812 | + { | |
813 | + startX = width2 - SCR_WIDTH; | |
814 | + } | |
815 | + if (startY >= height2 - SCR_HEIGHT) | |
816 | + { | |
817 | + startY = height2 - SCR_HEIGHT; | |
818 | + } | |
819 | + if (startX < 0) | |
820 | + { | |
821 | + startX = 0; | |
822 | + } | |
823 | + if (startY < 0) | |
824 | + { | |
825 | + startY = 0; | |
826 | + } | |
827 | + sx = thumb * startX; | |
828 | + sy = thumb * startY; | |
829 | + tex.w = BUF_WIDTH; | |
830 | + tex.h = BUF_HEIGHT; | |
831 | + tex.tb = width; | |
832 | + blt(img[0]+sx+sy*width, &tex, width - sx, height - sy, width2 - startX, height2 - startY); | |
833 | + if (menu) | |
834 | + { | |
835 | + pgCopyMenuBar(); | |
836 | + } | |
837 | + sceDisplayWaitVblankStart(); | |
838 | + framebuffer = sceGuSwapBuffers(); | |
839 | + } | |
840 | +} |
@@ -0,0 +1,36 @@ | ||
1 | +/* | |
2 | +* $Id$ | |
3 | +*/ | |
4 | + | |
5 | +#ifndef __PSP2CH_IMAGE_VIEW__ | |
6 | +#define __PSP2CH_IMAGE_VIEW__ | |
7 | + | |
8 | +typedef struct tagBITMAPFILEHEADER { | |
9 | + unsigned char bfType[2]; | |
10 | + unsigned long bfSize; | |
11 | + unsigned short bfReserved1; | |
12 | + unsigned short bfReserved2; | |
13 | + unsigned long bfOffBits; | |
14 | +} __attribute__ ((packed)) BITMAPFILEHEADER; | |
15 | + | |
16 | +typedef struct tagBITMAPINFOHEADER{ | |
17 | + unsigned long biSize; | |
18 | + long biWidth; | |
19 | + long biHeight; | |
20 | + unsigned short biPlanes; | |
21 | + unsigned short biBitCount; | |
22 | + unsigned long biCompression; | |
23 | + unsigned long biSizeImage; | |
24 | + long biXPixPerMeter; | |
25 | + long biYPixPerMeter; | |
26 | + unsigned long biClrUsed; | |
27 | + unsigned long biClrImporant; | |
28 | +} __attribute__ ((packed)) BITMAPINFOHEADER; | |
29 | + | |
30 | +int psp2chImageViewJpeg(char* fname); | |
31 | +int psp2chImageViewPng(char* fname); | |
32 | +int psp2chImageViewBmp(char* fname); | |
33 | +int psp2chImageViewGif(char* fname); | |
34 | +void psp2chImageViewer(int* img[], int width, int height, char* fname); | |
35 | + | |
36 | +#endif |