3 #if defined (__APPLE__) || defined (MACOSX)
5 #include <OpenGL/glext.h>
19 # define png_jmpbuf( png_ptr ) ( (png_ptr)->jmpbuf )
22 #if defined (_WIN32) && !defined (__CYGWIN__)
28 typedef unsigned char boolean;
34 #define DDS_CUBEMAP 0x00000200L
35 #define DDS_CUBEMAP_POSITIVEX 0x00000400L
36 #define DDS_CUBEMAP_NEGATIVEX 0x00000800L
37 #define DDS_CUBEMAP_POSITIVEY 0x00001000L
38 #define DDS_CUBEMAP_NEGATIVEY 0x00002000L
39 #define DDS_CUBEMAP_POSITIVEZ 0x00004000L
40 #define DDS_CUBEMAP_NEGATIVEZ 0x00008000L
41 #define DDS_CUBEMAP_ALLFACES \
42 (DDS_CUBEMAP_POSITIVEX|DDS_CUBEMAP_NEGATIVEX \
43 |DDS_CUBEMAP_POSITIVEY|DDS_CUBEMAP_NEGATIVEY \
44 |DDS_CUBEMAP_POSITIVEZ|DDS_CUBEMAP_NEGATIVEZ)
67 this->img_color_type = 8;
79 this->strip_16 =
false;
91 this->strip_16 = strip;
97 this->Init( f, t, strip, f2 );
108 this->Init( f, t, strip, f2 );
110 unsigned char *ret = NULL;
111 CheckFormat( img_file );
112 switch (this->img_type)
115 ret = this->ReadDDS();
118 ret = this->ReadPNG();
121 ret = this->ReadJPEG();
124 ret = this->ReadBMP();
127 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
142 unsigned char sig[8];
144 file->
Read( sig, 8 );
145 if ( png_sig_cmp( sig, 0, 8 ) )
161 file->
Read( sig, 13 );
167 if ( strncmp( sig+6,
"JFIF", 4 ) )
180 file->
Read( &head1, 1 );
181 file->
Read( &head2, 1 );
182 if (toupper( head1 ) !=
'B' || toupper( head2 ) !=
'M')
194 file->
Read( &ddsfile, 4 );
195 if (strncmp( ddsfile,
"DDS ", 4 ) != 0)
201 void VSImage::CheckFormat(
VSFile *file )
203 if (this->CheckDDSSignature( file ) ==
Ok) {
208 if (this->CheckPNGSignature( file ) ==
Ok) {
213 if (this->CheckBMPSignature( file ) ==
Ok) {
218 if (this->CheckJPEGSignature( file ) ==
Ok) {
227 vs_dprintf(3,
"Preparing to copy %u bytes from PngFileBuffer\n");
244 #ifndef PNG_NO_CONSOLE_IO
249 unsigned char* VSImage::ReadPNG()
251 png_bytepp row_pointers = NULL;
252 unsigned char *image = NULL;
262 if ( !CheckPNGSignature( img_file ) ) {
263 vs_dprintf(1,
"VSImage::ReadPNG() ERROR : NOT A PNG FILE\n");
264 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
269 if ( img_file->UseVolume() ) {
270 PngFileBuffer.
Buffer = img_file->get_pk3_data();
271 PngFileBuffer.
Pos = 8;
273 png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)
png_cexcept_error, (png_error_ptr) NULL );
274 if (png_ptr == NULL) {
275 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
278 info_ptr = png_create_info_struct( png_ptr );
279 if (info_ptr == NULL) {
280 png_destroy_read_struct( &png_ptr, (png_infopp) NULL, (png_infopp) NULL );
281 vs_dprintf(1,
"VSImage ERROR : PNG info_ptr == NULL !!!\n");
282 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
287 png_destroy_read_struct( &png_ptr, &info_ptr, (png_infopp) NULL );
289 vs_dprintf(1,
"VSImage ERROR : problem reading file/buffer -> setjmp !!!\n");
290 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
293 if ( !img_file->UseVolume() )
294 png_init_io( png_ptr, img_file->GetFP() );
296 png_set_read_fn( png_ptr, (png_voidp)&PngFileBuffer, (png_rw_ptr)
PngReadFunc );
297 png_set_sig_bytes( png_ptr, 8 );
298 vs_dprintf(3,
"Loading Done. Decompressing\n");
299 png_read_info( png_ptr, info_ptr );
304 this->img_sides = SIDE_SINGLE;
306 png_get_IHDR( png_ptr,
308 (png_uint_32*) &this->sizeX,
309 (png_uint_32*) &this->sizeY,
311 &this->img_color_type,
315 vs_dprintf(3,
"1. Loading a PNG file: width = %u , height = %u , depth = %u , img color = %u , intelace = %u \n", sizeX, sizeY, img_depth, img_color_type, interlace_type);
316 # if __BYTE_ORDER != __BIG_ENDIAN
317 if (this->img_depth == 16)
318 png_set_swap( png_ptr );
320 if (this->img_depth == 16 && strip_16)
321 png_set_strip_16( png_ptr );
322 if (strip_16 && this->img_color_type == PNG_COLOR_TYPE_PALETTE)
323 png_set_palette_to_rgb( png_ptr );
324 if (this->img_color_type == PNG_COLOR_TYPE_GRAY && this->img_depth < 8) {
325 png_set_expand_gray_1_2_4_to_8( png_ptr );
327 png_set_expand( png_ptr );
328 png_read_update_info( png_ptr, info_ptr );
332 png_get_IHDR( png_ptr,
334 (png_uint_32*) &this->sizeX,
335 (png_uint_32*) &this->sizeY,
337 &this->img_color_type,
341 vs_dprintf(3,
"2. Loading a PNG file : width = %u , height = %u , depth = %u , img_color = %u , interlace = %u\n",sizeX, sizeY, img_depth, img_color_type, interlace_type);
344 row_pointers = (
unsigned char**) malloc(
sizeof (
unsigned char*)*this->sizeY );
346 if (this->img_color_type&PNG_COLOR_MASK_COLOR)
348 if (this->img_color_type&PNG_COLOR_MASK_PALETTE)
350 if (this->img_color_type&PNG_COLOR_MASK_ALPHA)
354 else if (numchan == 3)
358 unsigned long stride = numchan*
sizeof (
unsigned char)*this->img_depth/8;
359 vs_dprintf(3,
"3. Allocating image buffer of size = %u \n",(stride*sizeX*sizeY));
360 image = (
unsigned char*) malloc( stride*this->sizeX*this->sizeY );
361 for (
unsigned int i = 0;
i < this->sizeY;
i++)
362 row_pointers[i] = &image[i*stride*this->sizeX];
363 png_read_image( png_ptr, row_pointers );
364 unsigned char *result;
366 vs_dprintf(3,
"4. Doing a transformation \n");
367 result = (*tt)(this->img_depth, this->img_color_type, this->sizeX, this->sizeY, row_pointers);
373 free( row_pointers );
375 png_read_end( png_ptr, info_ptr );
376 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
381 this->AllocatePalette();
389 free( row_pointers );
397 struct jpeg_error_mgr
pub;
408 (*cinfo->err->output_message)( cinfo );
414 unsigned char* VSImage::ReadJPEG()
416 unsigned char *image = NULL;
417 JSAMPARRAY row_pointers = NULL;
421 jpeg_decompress_struct cinfo;
425 cinfo.err = jpeg_std_error( &jerr.
pub );
426 jerr.
pub.error_exit = my_error_exit;
430 jpeg_destroy_decompress( &cinfo );
431 vs_dprintf(1 ,
"VSImage ERROR : error reading jpg file\n");
432 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
435 jpeg_create_decompress( &cinfo );
436 if ( !img_file->UseVolume() )
437 jpeg_stdio_src( (j_decompress_ptr)&cinfo, img_file->GetFP() );
439 jpeg_memory_src( &cinfo, (
unsigned char*) img_file->get_pk3_data(), img_file->Size() );
440 (void) jpeg_read_header( &cinfo,
TRUE );
441 this->sizeX = cinfo.image_width;
442 this->sizeY = cinfo.image_height;
444 this->img_sides = SIDE_SINGLE;
446 (void) jpeg_start_decompress( &cinfo );
448 this->img_color_type = PNG_COLOR_TYPE_RGB;
449 if (cinfo.output_components == 1)
450 this->img_color_type = PNG_COLOR_TYPE_GRAY;
451 else if (cinfo.output_components == 4)
452 this->img_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
453 else if (cinfo.output_components == 2)
454 this->img_color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
455 switch (this->img_color_type)
457 case PNG_COLOR_TYPE_RGB:
460 case PNG_COLOR_TYPE_RGB_ALPHA:
461 this->mode = _24BITRGBA;
463 case PNG_COLOR_TYPE_GRAY:
466 case PNG_COLOR_TYPE_GRAY_ALPHA:
470 vs_dprintf(3,
"1. Loading a JPEG file : width= %u , height = %u , img_color = %u \n",sizeX, sizeY, img_color_type);
471 row_pointers = (
unsigned char**) malloc(
sizeof (
unsigned char*)*cinfo.image_height );
474 int numchan = cinfo.output_components;
476 unsigned long stride = numchan*
sizeof (
unsigned char)*this->img_depth/8;
477 image = (
unsigned char*) malloc( stride*cinfo.image_width*cinfo.image_height );
478 for (
unsigned int i = 0;
i < cinfo.image_height;
i++)
479 row_pointers[i] = &image[i*stride*cinfo.image_width];
480 unsigned int count = 0;
481 while (count < this->sizeY)
482 count += jpeg_read_scanlines( &cinfo, &(row_pointers[count]), this->sizeY-count );
483 (void) jpeg_finish_decompress( &cinfo );
484 jpeg_destroy_decompress( &cinfo );
486 unsigned char *result = image;
488 result = (*tt)(this->img_depth, this->img_color_type, this->sizeX, this->sizeY, row_pointers);
492 free( row_pointers );
495 this->AllocatePalette();
499 if (image) free( image );
501 if (row_pointers) free( row_pointers );
507 unsigned char* VSImage::ReadBMP()
509 unsigned char *data = NULL;
510 unsigned char *cdata = NULL;
511 unsigned char *adata = NULL;
514 if (CheckBMPSignature( img_file ) !=
Ok) {
515 vs_dprintf(1,
"VSImage ERROR : BMP signature check failed : this should not happen !!!\n");
516 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
526 this->img_sides = SIDE_SINGLE;
549 if ( img_file2 && img_file2->Valid() )
551 int ncomp = ( (mode == _24BIT) ? 3 : 4 );
552 unsigned int cstride = ( (
sizeof (
unsigned char)*3*this->sizeX)+3 )&~3;
553 unsigned int astride = ( (
sizeof (
unsigned char)*this->sizeX)+3 )&~3;
554 unsigned int stride = (
sizeof (
unsigned char)*ncomp*this->sizeX);
555 data = (
unsigned char*) malloc( stride*this->sizeY );
556 if (data == NULL)
return NULL;
557 if (mode != _24BIT) {
558 cdata = (
unsigned char*) malloc( cstride );
559 adata = (
unsigned char*) malloc( astride );
560 if ( (cdata == NULL) || (adata == NULL) )
throw (
"memory");
561 unsigned char *row = data+(this->sizeY-1)*stride;
562 for (
unsigned int i = 0;
i < this->sizeY;
i++, row -= stride) {
563 img_file->Read( cdata, cstride );
564 img_file2->Read( adata, astride );
565 unsigned char *cpix = cdata, *apix = adata, *pix = row;
566 for (
unsigned int j = 0;
j < this->sizeX;
j++, cpix += 3, apix++, pix += 4) {
578 unsigned char *row = data+(this->sizeY-1)*stride;
580 for (
unsigned int i = 0;
i < this->sizeY;
i++, row -= stride) {
581 img_file->Read( row, stride );
582 if (cstride > stride) {
583 assert( cstride-stride <
sizeof (dummy) );
584 img_file->Read( &dummy, cstride-stride );
586 unsigned char *pix = row;
587 for (
unsigned int j = 0;
j < this->sizeX;
j++, pix += 3) {
588 unsigned char apix = pix[0];
597 data = (
unsigned char*) malloc(
sizeof (
unsigned char)*sizeY*sizeX );
598 this->palette = (
unsigned char*) malloc(
sizeof (
unsigned char)*(256*4+1) );
599 memset( this->palette, 0, (256*4+1)*
sizeof (
unsigned char) );
600 unsigned char *paltemp = this->palette;
602 for (
int palcount = 0; palcount < 256; palcount++) {
605 paltemp[0] = paltemp[2];
611 for (
int i = sizeY-1;
i >= 0;
i--)
612 for (
unsigned int j = 0;
j < sizeX;
j++)
613 img_file->Read( data+j+i*sizeX,
sizeof (
unsigned char) );
618 if (cdata) free( cdata );
620 if (adata) free( adata );
622 if (data) free( data );
629 #define IS_POT( x ) ( !( (x)& ( (x)-1 ) ) )
631 unsigned char* VSImage::ReadDDS()
634 unsigned int internal = GL_NONE, type = GL_RGB;
636 unsigned char *s = NULL;
637 unsigned int inputSize = 0;
645 img_file->Read( ibuffer, 4 );
647 img_file->Read( ibuffer, 4 );
649 img_file->Read( ibuffer, 4 );
651 img_file->Read( ibuffer, 4 );
653 img_file->Read( ibuffer, 4 );
655 img_file->Read( ibuffer, 4 );
657 img_file->Read( ibuffer, 4 );
659 img_file->GoTo( 84 );
661 img_file->Read( ibuffer, 4 );
663 img_file->GoTo( 108 );
664 img_file->Read( ibuffer, 4 );
666 img_file->Read( ibuffer, 4 );
668 img_file->GoTo( 128 );
671 this->sizeX = header.
width;
672 this->sizeY = header.
height;
674 bool useDefaultType =
false;
675 switch (this->img_depth)
679 this->img_alpha =
false;
683 this->img_alpha =
true;
689 type = GL_LUMINANCE_ALPHA;
690 this->img_alpha =
true;
693 useDefaultType =
true;
696 useDefaultType =
true;
703 if (type == GL_RGB || useDefaultType) {
704 this->img_depth = 24;
706 this->img_alpha =
false;
709 this->mode = _DXT1RGBA;
711 this->img_alpha =
true;
716 if (useDefaultType) {
717 this->img_alpha =
true;
718 this->img_depth = 32;
724 if (useDefaultType) {
725 this->img_alpha =
true;
726 this->img_depth = 32;
733 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
737 width = header.
width;
739 img_sides = SIDE_SINGLE;
740 img_nmips = header.
nmips;
742 if (header.
nmips == 0)
743 inputSize = ( (width+3)/4 )*( (height+3)/4 )*blockSize;
744 for (
int i = 0;
i < header.
nmips; ++
i) {
745 inputSize += ( (width+3)/4 )*( (height+3)/4 )*blockSize;
752 vs_dprintf(3,
"Reading Cubemap %s\n", img_file->GetFilename().c_str() );
753 inputSize = inputSize*6;
755 SIDE_POS_X|SIDE_NEG_X
756 |SIDE_POS_Y|SIDE_NEG_Y
757 |SIDE_POS_Z|SIDE_NEG_Z;
758 this->img_color_type = 998;
760 this->img_color_type = 999;
762 s = (
unsigned char*) malloc( inputSize+3 );
763 sprintf( (
char*) s,
"%i", header.
nmips );
764 img_file->Read( s+2, inputSize );
779 void VSImage::AllocatePalette()
783 if ( !(img_color_type&PNG_HAS_COLOR) ) {
784 palette = (
unsigned char*) malloc(
sizeof (
unsigned char)*(256*4+1) );
785 for (
unsigned int i = 0;
i < 256;
i++) {
789 palette[
i*4+3] = 255;
805 this->img_type = type;
809 vs_dprintf(1,
"VSImage ERROR : failed to open %s for writing \n",filename);
810 vs_dprintf( 1, img_file->GetFilename().c_str() );
813 VSError ret = this->WriteImage( &f, data, type, width, height, alpha, bpp, flip );
830 this->img_depth = bpp;
833 this->img_alpha = alpha;
838 ret = this->WritePNG( data );
841 ret = this->WriteJPEG( data );
844 ret = this->WriteBMP( data );
847 vs_dprintf(1,
"VSImage ERROR : Unknown image format\n");
848 vs_dprintf( 1,
"%s\n", img_file->GetFilename().c_str() );
851 this->img_file = NULL;
855 this->img_alpha =
false;
859 VSError VSImage::WritePNG(
unsigned char *data )
861 png_structp png_ptr = png_create_write_struct
862 ( PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL );
865 png_infop info_ptr = png_create_info_struct( png_ptr );
867 png_destroy_write_struct( &png_ptr, (png_infopp) NULL );
871 png_destroy_write_struct( &png_ptr, &info_ptr );
876 png_init_io( png_ptr, img_file->GetFP() );
878 png_set_filter( png_ptr, 0, PNG_FILTER_NONE );
879 png_set_compression_level( png_ptr, Z_BEST_COMPRESSION );
882 png_set_compression_mem_level( png_ptr, 8 );
883 png_set_compression_strategy( png_ptr, Z_DEFAULT_STRATEGY );
884 png_set_compression_window_bits( png_ptr, 15 );
885 png_set_compression_method( png_ptr, 8 );
887 png_set_IHDR( png_ptr,
892 this->img_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
894 PNG_COMPRESSION_TYPE_DEFAULT,
895 PNG_FILTER_TYPE_DEFAULT );
897 png_write_info( png_ptr, info_ptr );
898 # if __BYTE_ORDER != __BIG_ENDIAN
899 if (this->img_depth == 16)
900 png_set_swap( png_ptr );
902 int stride = (this->img_depth/8)*(this->img_alpha ? 4 : 3);
903 png_byte **row_pointers =
new png_byte*[this->sizeY];
905 for (
int i = this->sizeY-1, j = 0;
i >= 0;
i--, ++
j)
906 row_pointers[j] = (png_byte*) &data[stride*
i*sizeX];
908 for (
unsigned int i = 0;
i < this->sizeY;
i++)
909 row_pointers[i] = (png_byte*) &data[stride*
i*sizeX];
910 png_write_image( png_ptr, row_pointers );
911 png_write_end( png_ptr, info_ptr );
912 png_write_flush( png_ptr );
913 png_destroy_write_struct( &png_ptr, &info_ptr );
916 delete[] row_pointers;
920 VSError VSImage::WriteJPEG(
unsigned char *data )
925 VSError VSImage::WriteBMP(
unsigned char *data )