// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) // All rights reserved. // // This file is part of the ImageIO Library, and as been adapted for // CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the // GNU Lesser General Public License as published by the Free Software Foundation; // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau #ifdef CGAL_HEADER_ONLY #define CGAL_INLINE_FUNCTION inline #else #define CGAL_INLINE_FUNCTION #endif #include #include #include #include #include /** Magic header for bmp */ #define BMP_MAGIC "BM" #ifdef CGAL_HEADER_ONLY inline int& get_static_verbose_bmp() { static int _VERBOSE_BMP_ = 1; return _VERBOSE_BMP_; } #else // CGAL_HEADER_ONLY static int _VERBOSE_BMP_ = 1; inline int& get_static_verbose_bmp() { return _VERBOSE_BMP_; } #endif // CGAL_HEADER_ONLY CGAL_INLINE_FUNCTION int testBmpHeader(char *magic,const char *) { if( !strncmp(magic, BMP_MAGIC, strlen(BMP_MAGIC))) return 0; else return -1; } CGAL_INLINE_FUNCTION PTRIMAGE_FORMAT createBMPFormat() { PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); f->testImageFormat=&testBmpHeader; f->readImageHeader=&readBmpImage; f->writeImage=0; strcpy(f->fileExtension,".bmp"); strcpy(f->realName,"BMP"); return f; } CGAL_INLINE_FUNCTION int readBmpImage( const char *name,_image *im) { int dimx, dimy, dimv; im->data = _readBmpImage( name, &dimx, &dimy, &dimv ); if ( im->data == NULL ) { fprintf( stderr, "readBmpImage: unable to read \'%s\'\n", name ); return( -1 ); } im->xdim = dimx; im->ydim = dimy; im->vdim = dimv; im->zdim = 1; im->wdim = 1; im->wordKind = WK_FIXED; im->sign = SGN_UNSIGNED; return 1; } CGAL_INLINE_FUNCTION void *_readBmpImage( const char *name, int *dimx, int *dimy, int *dimz ) { const char *proc="_readBmpImage"; void *buf = (void*)NULL; unsigned char *myBuf = NULL; FILE *fp = NULL; RGB **argbs = NULL; char **xorMasks = NULL, **andMasks = NULL; CGAL_UINT32 *heights = NULL, *widths = NULL, row = 0, col = 0; CGAL_UINT16 fileType = 0; long filePos = 0; int numImages = 0, i = 0; int rc = 0; fp = fopen(name, "rb"); if (fp == NULL) { if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: error in opening %s\n", proc, name ); return( (void*)NULL ); } /* * Read the first two bytes as little-endian to determine the file type. * Preserve the file position. */ filePos = ftell(fp); rc = readUINT16little(fp, &fileType); if (rc != 0) { fclose(fp); if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: error in getting file type %s\n", proc, name ); return( (void*)NULL ); } fseek(fp, filePos, SEEK_SET); /* * Read the images. */ switch (fileType) { case TYPE_ARRAY: /* * If this is an array of images, read them. All the arrays we need * will be allocated by the reader function. */ rc = readMultipleImage(fp, &argbs, &xorMasks, &andMasks, &heights, &widths, &numImages); break; case TYPE_BMP: case TYPE_ICO: case TYPE_ICO_COLOR: case TYPE_PTR: case TYPE_PTR_COLOR: /* * If this is a single-image file, we've a little more work. In order * to make the output part of this test program easy to write, we're * going to allocate dummy arrays that represent what * readMultipleImage would have allocated. We'll read the data into * those arrays. */ argbs = (RGB **)calloc(1, sizeof(RGB *)); if (argbs == NULL) { rc = 1005; break; } xorMasks = (char **)calloc(1, sizeof(char *)); if (xorMasks == NULL) { free(argbs); rc = 1005; break; } andMasks = (char **)calloc(1, sizeof(char *)); if (andMasks == NULL) { free(argbs); free(xorMasks); rc = 1005; break; } heights = (CGAL_UINT32 *)calloc(1, sizeof(CGAL_UINT32)); if (heights == NULL) { free(argbs); free(xorMasks); free(andMasks); rc = 1005; break; } widths = (CGAL_UINT32 *)calloc(1, sizeof(CGAL_UINT32)); if (widths == NULL) { free(argbs); free(xorMasks); free(andMasks); free(heights); rc = 1005; break; } numImages = 1; /* * Now that we have our arrays allocted, read the image into them. */ switch (fileType) { case TYPE_BMP: rc = readSingleImageBMP(fp, argbs, widths, heights); break; case TYPE_ICO: case TYPE_PTR: rc = readSingleImageICOPTR(fp, xorMasks, andMasks, widths, heights); break; case TYPE_ICO_COLOR: case TYPE_PTR_COLOR: rc = readSingleImageColorICOPTR(fp, argbs, xorMasks, andMasks, widths, heights); break; } break; default: rc = 1000; } fclose(fp); /* * At this point, everything's been read. Display status messages based * on the return values. */ switch (rc) { case 1000: case 1006: if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: File is not a valid bitmap file\n", proc ); break; case 1001: if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: Illegal information in an image\n", proc ); break; case 1002: if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: Legal information that I can't handle yet in an image\n", proc ); break; case 1003: case 1004: case 1005: if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: Ran out of memory\n", proc ); break; case 0: if ( get_static_verbose_bmp() > 1 ) fprintf( stderr, "%s: Got good data from file, writing results\n", proc ); break; default: if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: Error reading file rc=%d\n", proc,rc ); break; } /* * If the return value wasn't 0, something went wrong. */ if (rc != 0) { if (rc != 1000 && rc != 1005) { for (i=0; i 1 ) fprintf (stderr, "%s: There are %d images in the file\n", proc, numImages); if ( numImages >= 2 ) fprintf (stderr, "%s: read only first image among %d\n", proc, numImages ); /* * my stuff: * just reading one bmp image */ if ( (numImages > 0) && (argbs[0] != NULL) ) { buf = (void*)malloc( widths[0]*heights[0]*3 * sizeof( unsigned char ) ); if ( buf == (void*)NULL ) { if ( get_static_verbose_bmp() ) fprintf( stderr, "%s: error in allocating data buffer for %s\n", proc, name ); for (i=0; i