home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <malloc.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <string.h>
- #include <iostream>
-
- #include "image.h"
-
- #define IMAGE_TEXT_OUT 1
-
- Image::Image () {
- paleta = 0;
- bitmap = 0;
- h = w = 0;
- form = OGL_IMAGE_NULL;
- }
-
- Image::Image (const char* filename) {
- paleta = 0;
- bitmap = 0;
- h = w = 0;
- form = OGL_IMAGE_NULL;
- Load(filename);
- }
-
- Image::~Image () {
- delete[] paleta;
- delete[] bitmap;
- }
-
- void Image::Scale(int sirka, int vyska)
- {
- int elementsize = 0;
- switch(format()) {
- case OGL_IMAGE_RGBA8888:
- case OGL_IMAGE_ARGB8888:
- elementsize = 4;
- break;
- case OGL_IMAGE_RGB888:
- elementsize = 3;
- break;
- case OGL_IMAGE_INDEX8:
- case OGL_IMAGE_LUMINANCE8:
- elementsize = 1;
- break;
- default:
- return;
- }
-
- // vyska=h;
- // sirka=w;
-
- unsigned char* n_bitmap = new unsigned char[vyska*sirka*elementsize];
- unsigned char* n=n_bitmap;
- unsigned char* p, *pp;
-
- float xx=0.0,yy=0.0;
-
- float dx=float(w)/sirka;
- float dy=float(h)/vyska;
-
- for (int y=0; y<vyska;y++)
- {
- p=bitmap+(int(yy))*elementsize*w;
- for (int x=0; x<sirka;x++)
- {
- pp=p+(int(xx))*elementsize;
- for(int i=elementsize;i;i--) *n++=*pp++;
- xx+=dx;
- }
- xx=0.0;
- yy+=dy;
- }
- delete[] bitmap;
- bitmap=n_bitmap;
- w=sirka;
- h=vyska;
- }
-
- void Image::FlipVertical () {
- int elementsize = 0;
- switch(format()) {
- case OGL_IMAGE_RGBA8888:
- case OGL_IMAGE_ARGB8888:
- elementsize = 4;
- break;
- case OGL_IMAGE_RGB888:
- elementsize = 3;
- break;
- case OGL_IMAGE_INDEX8:
- case OGL_IMAGE_LUMINANCE8:
- elementsize = 1;
- break;
- default:
- return;
- }
- unsigned char *p1, *p2, *pp1, *pp2;
- unsigned char x;
- int linewidth = width()*elementsize;
- p1 = data();
- p2 = p1 + linewidth*(height()-1);
- int half = height()/2;
-
- for(int i=half; i; i--) {
- pp1 = p1;
- pp2 = p2;
- for(int j=linewidth; j; j--) {
- x = *pp1;
- *pp1 = *pp2;
- *pp2 = x;
- pp1++;
- pp2++;
- }
- p1+=linewidth;
- p2-=linewidth;
- }
- }
-
-
- int Image::LoadBMP (const char* filename)
- {
- int f;
- struct stat *st;
- st = (struct stat *) malloc(sizeof(*st));
-
- f = open(filename, O_BINARY|O_RDONLY);
- if (f==(-1))
- return 0;
-
- fstat(f,st);
- int filesize = st->st_size;
- unsigned char *buffer = new unsigned char[filesize];
- read(f, buffer, filesize);
- close(f);
- free(st);
-
- header.bfType = *(short*)buffer;
- if(header.bfType!=0x4d42)
- return 0;
-
- header.bfSize = *(long*)(buffer+2);
- header.bfReserved1 = *(short*)(buffer+6);
- header.bfReserved2 = *(short*)(buffer+8);
- header.bfOffBits = *(long*)(buffer+10);
-
- header.biSize = *(long*)(buffer+14);
- header.biWidth = *(long*)(buffer+18);
- header.biHeight = *(long*)(buffer+22);
- header.biPlanes = *(short*)(buffer+26);
- header.biBitCount = *(short*)(buffer+28);
- header.biCompression = *(long*)(buffer+30);
- header.biSizeImage = *(long*)(buffer+34);
- header.biXPelsPerMeter = *(long*)(buffer+38);
- header.biYPelsPerMeter = *(long*)(buffer+42);
- header.biClrUsed = *(long*)(buffer+46);
- header.biClrImportant = *(long*)(buffer+50);
- /*
- if (IMAGE_TEXT_OUT) printf("bmp size: %ld\n", header.bfSize);
- if (IMAGE_TEXT_OUT) printf("width: %ld\n",header.biWidth);
- if (IMAGE_TEXT_OUT) printf("height: %ld\n",header.biHeight);
- if (IMAGE_TEXT_OUT) printf("planes: %hd\n",header.biPlanes);
- if (IMAGE_TEXT_OUT) printf("bpp: %hd\n",header.biBitCount);
- if (IMAGE_TEXT_OUT) printf("compression: %ld\n",header.biCompression);
- header.biClrUsed ? if (IMAGE_TEXT_OUT) printf(" colors used: %ld, ",header.biClrUsed)
- : if (IMAGE_TEXT_OUT) printf(" colors used: ALL, ");
- header.biClrImportant ? if (IMAGE_TEXT_OUT) printf("colors important: %ld\n",header.biClrImportant)
- : if (IMAGE_TEXT_OUT) printf("colors important: ALL\n");
- */
- w = header.biWidth;
- h = header.biHeight;
- bpp = header.biBitCount;
-
- unsigned char *data;
- unsigned char *map, *map2;
- unsigned char *pal;
- int actualcolors;
-
- switch(bpp) {
-
- // Monochromatic
- case 1:
- break;
-
- // Indexed 16 color
- case 4:
- break;
-
- // Indexed 256 color
- case 8:
- form = OGL_IMAGE_INDEX8;
- paleta = new unsigned long[256];
- pal = buffer + 54;
- actualcolors = header.biClrUsed ? header.biClrUsed : 256;
- for(int i=0; i<actualcolors; i++, pal+=4)
- paleta[i] = (*pal) | (*(pal+1)<<8) | (*(pal+2)<<16);
-
- data = buffer + header.bfOffBits;
- bitmap = new unsigned char[h*w];
-
- switch(header.biCompression) {
-
- case BMP_RGB:
- map = bitmap + w*(h-1);
-
- for(int i=h; i; i--)
- {
- map2=map;
-
- for(int j=w; j; j--)
- *map2++ = *data++;
-
- map -= w;
- }
- break;
-
- case BMP_RLE8:
- break;
-
- case BMP_RLE4:
- break;
- }
-
- break;
-
- // 24bpp images
- case 24:
- form = OGL_IMAGE_RGBA8888;
- data = buffer + header.bfOffBits;
- bitmap = new unsigned char[(h*w)<<2];
-
- map = bitmap;
-
- for(int i=h*w; i; i--)
- {
- *map++ = *(data+2);
- *map++ = *(data+1);
- *map++ = *data;
- *map++ = 255;
- data+=3;
-
- // *map++ = *data++;
- // *map++ = *data++;
- // *map++ = *data++;
- // *map++ = 255;
- }
-
- FlipVertical();
-
- break;
-
- }
-
- free(buffer);
- return 1;
- }
-
- int Image::LoadPNG (const char* filename) {
-
- FILE *fp = fopen(filename, "rb");
-
- if(!fp)
- {
- if (IMAGE_TEXT_OUT) printf("file %s not found\n", filename);
- return 0;
- }
-
- png_structp png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)0,
- 0, 0);
- if (!png_ptr)
- {
- if (IMAGE_TEXT_OUT) printf("png read structure cannot be created\n");
- fclose(fp);
- return 0;
- }
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- if (IMAGE_TEXT_OUT) printf("png info structure cannot be created\n");
- png_destroy_read_struct(&png_ptr,
- (png_infopp)0, (png_infopp)0);
- fclose(fp);
- return 0;
- }
-
- png_infop end_info = png_create_info_struct(png_ptr);
- if (!end_info)
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)0);
- fclose(fp);
- return 0;
- }
-
- png_init_io(png_ptr, fp);
- png_read_info(png_ptr, info_ptr);
-
- w = png_get_image_width(png_ptr, info_ptr);
- h = png_get_image_height(png_ptr, info_ptr);
-
- png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
- png_byte color_type = png_get_color_type(png_ptr, info_ptr);
-
- if(bit_depth == 8 && color_type == PNG_COLOR_TYPE_PALETTE)
- {
- form = OGL_IMAGE_INDEX8;
- png_bytep rowpointers[h];
- bitmap = new unsigned char[h*w];
- paleta = new unsigned long[256];
- png_colorp pngpal;
- int num_palette;
- bpp=bit_depth;
-
- png_get_PLTE(png_ptr, info_ptr, &pngpal, &num_palette);
-
- for(png_uint_16 i=0; i<num_palette; i++)
- paleta[i] = (pngpal[i].red<<16)|(pngpal[i].green<<8)|(pngpal[i].blue);
-
- for(long i=0; i<h; i++)
- rowpointers[i] = (png_bytep)(bitmap+i*w);
-
- png_read_image(png_ptr, rowpointers);
-
- png_read_end(png_ptr, end_info);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- fclose(fp);
- return 1;
- }
-
- if(bit_depth == 8 && color_type == PNG_COLOR_TYPE_GRAY)
- {
- // if (IMAGE_TEXT_OUT) printf("Grayscale ");
- form = OGL_IMAGE_LUMINANCE8;
- png_bytep rowpointers[h];
- bitmap = new unsigned char[h*w];
- bpp=bit_depth;
- for(long i=0; i<h; i++)
- rowpointers[i] = (png_bytep)(bitmap+i*w);
-
- png_read_image(png_ptr, rowpointers);
- png_read_end(png_ptr, end_info);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- // if (IMAGE_TEXT_OUT) printf("%s\n",filename);
-
- fclose(fp);
- return 1;
- }
-
-
- if(bit_depth == 8 && color_type == PNG_COLOR_TYPE_RGB)
- {
- form = OGL_IMAGE_RGBA8888;
- png_bytep rowpointers[h];
- bitmap = new unsigned char[h*w*4];
- bpp=bit_depth;
-
- for(long i=0; i<h; i++)
- rowpointers[i] = (png_bytep)(bitmap+i*w*4);
-
- // png_set_bgr(png_ptr);
- png_set_filler(png_ptr, 255, PNG_FILLER_AFTER);
-
- png_read_update_info(png_ptr, info_ptr);
-
- png_read_image(png_ptr, rowpointers);
-
- png_read_end(png_ptr, end_info);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- fclose(fp);
- return 1;
- }
-
- if(bit_depth == 8 && color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- form = OGL_IMAGE_RGBA8888;
- png_bytep rowpointers[h];
- bitmap = new unsigned char[h*w*4];
- bpp=bit_depth;
-
- for(long i=0; i<h; i++)
- rowpointers[i] = (png_bytep)(bitmap+i*w*4);
-
- // png_set_bgr(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
- png_read_image(png_ptr, rowpointers);
- png_read_end(png_ptr, end_info);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- fclose(fp);
- return 1;
- }
-
- png_read_end(png_ptr, end_info);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- fclose(fp);
- return 0;
- }
-
- int Image::LoadJPG(const char *filename)
- {
- struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
-
- FILE * infile; /* source file */
- int row_stride; /* physical row width in output buffer */
-
- if ((infile = fopen(filename, "rb")) == 0) {
- if (IMAGE_TEXT_OUT) fprintf(stderr, "can't open %s\n", filename);
- return 0;
- }
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, infile);
- jpeg_read_header(&cinfo, TRUE);
- jpeg_start_decompress(&cinfo);
- row_stride = cinfo.output_width * cinfo.output_components;
-
- if (IMAGE_TEXT_OUT) cout<<"width: " << cinfo.output_width << ",";
- if (IMAGE_TEXT_OUT) cout<<"height: " << cinfo.output_height << ",";
- if (IMAGE_TEXT_OUT) cout<<"components: " <<cinfo.output_components << endl;
-
- bitmap = new unsigned char[row_stride*cinfo.output_height];
- w = cinfo.output_width;
- h = cinfo.output_height;
- form = OGL_IMAGE_RGB888;
- bpp = cinfo.output_components << 3;
-
- JSAMPROW row_pointer[1];
- int i=0;
-
- while (cinfo.output_scanline < cinfo.output_height) {
- row_pointer[0] = bitmap+i*row_stride;
- i++;
- jpeg_read_scanlines(&cinfo, row_pointer, 1);
- }
-
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(infile);
- return 1;
- }
-
- const char *getext(const char *str) {
- const char *ext = 0;
- while(*str)
- {
- if(*str==46) ext=str+1;
- str++;
- }
- if(*ext==0)
- ext = 0;
- return ext;
- }
-
- int Image::Load(const char *filename)
- {
- const char *extension = getext(filename);
-
- if(stricmp(extension, "bmp")==0) {
- return LoadBMP(filename);
- }
- if(stricmp(extension, "png")==0) {
- return LoadPNG(filename);
- }
- if(stricmp(extension, "jpg")==0) {
- return LoadJPG(filename);
- }
- return 0;
- }