- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-IL/src/il_wbmp.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2009 by Denton Woods
    00005 // Last modified: 01/04/2009
    00006 //
    00007 // Filename: src-IL/src/il_wbmp.c
    00008 //
    00009 // Description: Reads from a .wbmp file.  Specs available from
    00010 //                              http://www.ibm.com/developerworks/wireless/library/wi-wbmp/
    00011 //
    00012 //-----------------------------------------------------------------------------
    00013
    00014
    00015 #include "il_internal.h"
    00016 #ifndef IL_NO_WBMP
    00017 #include "il_bits.h"
    00018
    00019
    00020 ILboolean       iLoadWbmpInternal(void);
    00021 ILuint          WbmpGetMultibyte(void);
    00022 ILboolean       iSaveWbmpInternal(void);
    00023
    00024 // Reads a .wbmp file
    00025 ILboolean ilLoadWbmp(ILconst_string FileName)
    00026 {
    00027         ILHANDLE        WbmpFile;
    00028         ILboolean       bWbmp = IL_FALSE;
    00029
    00030         WbmpFile = iopenr(FileName);
    00031         if (WbmpFile == NULL) {
    00032                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00033                 return bWbmp;
    00034         }
    00035
    00036         iSetInputFile(WbmpFile);
    00037
    00038         bWbmp = ilLoadWbmpF(WbmpFile);
    00039
    00040         icloser(WbmpFile);
    00041
    00042         return bWbmp;
    00043 }
    00044
    00045
    00047 ILboolean ilLoadWbmpF(ILHANDLE File)
    00048 {
    00049         ILuint          FirstPos;
    00050         ILboolean       bRet;
    00051
    00052         iSetInputFile(File);
    00053         FirstPos = itell();
    00054         bRet = iLoadWbmpInternal();
    00055         iseek(FirstPos, IL_SEEK_SET);
    00056
    00057         return bRet;
    00058 }
    00059
    00060
    00062 ILboolean ilLoadWbmpL(const void *Lump, ILuint Size)
    00063 {
    00064         iSetInputLump(Lump, Size);
    00065         return iLoadWbmpInternal();
    00066 }
    00067
    00068
    00069 ILboolean iLoadWbmpInternal(void)
    00070 {
    00071         ILuint  Width, Height, BitPadding, i;
    00072         BITFILE *File;
    00073         ILubyte Padding[8];
    00074
    00075         if (iCurImage == NULL) {
    00076                 ilSetError(IL_ILLEGAL_OPERATION);
    00077                 return IL_FALSE;
    00078         }
    00079
    00080         if (igetc() != 0 || igetc() != 0) {  // The first two bytes have to be 0 (the "header")
    00081                 ilSetError(IL_INVALID_FILE_HEADER);
    00082                 return IL_FALSE;
    00083         }
    00084
    00085         Width = WbmpGetMultibyte();  // Next follows the width and height.
    00086         Height = WbmpGetMultibyte();
    00087
    00088         if (Width == 0 || Height == 0) {  // Must have at least some height and width.
    00089                 ilSetError(IL_INVALID_FILE_HEADER);
    00090                 return IL_FALSE;
    00091         }
    00092
    00093         if (!ilTexImage(Width, Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL))
    00094                 return IL_FALSE;
    00095         iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;  // Always has origin in the upper left.
    00096
    00097         BitPadding = (8 - (Width % 8)) % 8;  // Has to be aligned on a byte boundary.  The rest is padding.
    00098         File = bfile(iGetFile());
    00099         if (File == NULL)
    00100                 return IL_FALSE;
    00101
    00102         //@TODO: Do this without bread?  Would be faster, since we would not have to do
    00103         //  the second loop.
    00104
    00105         // Reads the bits
    00106         for (i = 0; i < iCurImage->Height; i++) {
    00107                 bread(&iCurImage->Data[iCurImage->Width * i], 1, iCurImage->Width, File);
    00108                 //bseek(File, BitPadding, IL_SEEK_CUR);  //@TODO: This function does not work correctly.
    00109                 bread(Padding, 1, BitPadding, File);  // Skip padding bits.
    00110         }
    00111         // Converts bit value of 1 to white and leaves 0 at 0 (2-colour images only).
    00112         for (i = 0; i < iCurImage->SizeOfData; i++) {
    00113                 if (iCurImage->Data[i] == 1)
    00114                         iCurImage->Data[i] = 0xFF;  // White
    00115         }
    00116
    00117         bclose(File);
    00118
    00119         return IL_TRUE;
    00120 }
    00121
    00122
    00123 ILuint WbmpGetMultibyte()
    00124 {
    00125         ILuint Val = 0, i;
    00126         ILubyte Cur;
    00127
    00128         for (i = 0; i < 5; i++) {  // Should not be more than 5 bytes.
    00129                 Cur = igetc();
    00130                 Val = (Val << 7) | (Cur & 0x7F);  // Drop the MSB of Cur.
    00131                 if (!(Cur & 0x80)) {  // Check the MSB and break if 0.
    00132                         break;
    00133                 }
    00134         }
    00135
    00136         return Val;
    00137 }
    00138
    00139
    00140 ILboolean WbmpPutMultibyte(ILuint Val)
    00141 {
    00142         ILint   i, NumBytes = 0;
    00143         ILuint  MultiVal = Val;
    00144
    00145         do {
    00146                 MultiVal >>= 7;
    00147                 NumBytes++;
    00148         } while (MultiVal != 0);
    00149
    00150         for (i = NumBytes - 1; i >= 0; i--) {
    00151                 MultiVal = (Val >> (i * 7)) & 0x7F;
    00152                 if (i != 0)
    00153                         MultiVal |= 0x80;
    00154                 iputc(MultiVal);
    00155         }
    00156
    00157         return IL_TRUE;
    00158 }
    00159
    00160
    00162 ILboolean ilSaveWbmp(const ILstring FileName)
    00163 {
    00164         ILHANDLE        WbmpFile;
    00165         ILuint          WbmpSize;
    00166
    00167         if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
    00168                 if (iFileExists(FileName)) {
    00169                         ilSetError(IL_FILE_ALREADY_EXISTS);
    00170                         return IL_FALSE;
    00171                 }
    00172         }
    00173
    00174         WbmpFile = iopenw(FileName);
    00175         if (WbmpFile == NULL) {
    00176                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00177                 return IL_FALSE;
    00178         }
    00179
    00180         WbmpSize = ilSaveWbmpF(WbmpFile);
    00181         iclosew(WbmpFile);
    00182
    00183         if (WbmpSize == 0)
    00184                 return IL_FALSE;
    00185         return IL_TRUE;
    00186 }
    00187
    00188
    00190 ILuint ilSaveWbmpF(ILHANDLE File)
    00191 {
    00192         ILuint Pos;
    00193         iSetOutputFile(File);
    00194         Pos = itellw();
    00195         if (iSaveWbmpInternal() == IL_FALSE)
    00196                 return 0;  // Error occurred
    00197         return itellw() - Pos;  // Return the number of bytes written.
    00198 }
    00199
    00200
    00202 ILuint ilSaveWbmpL(void *Lump, ILuint Size)
    00203 {
    00204         ILuint Pos = itellw();
    00205         iSetOutputLump(Lump, Size);
    00206         if (iSaveWbmpInternal() == IL_FALSE)
    00207                 return 0;  // Error occurred
    00208         return itellw() - Pos;  // Return the number of bytes written.
    00209 }
    00210
    00211
    00212 // In il_quantizer.c
    00213 ILimage *iQuantizeImage(ILimage *Image, ILuint NumCols);
    00214 // In il_neuquant.c
    00215 ILimage *iNeuQuant(ILimage *Image, ILuint NumCols);
    00216
    00217
    00218 // Internal function used to save the Wbmp.
    00219 ILboolean iSaveWbmpInternal()
    00220 {
    00221         ILimage *TempImage = NULL;
    00222         ILuint  i, j;
    00223         ILint   k;
    00224         ILubyte Val;
    00225         ILubyte *TempData;
    00226
    00227         iputc(0);  // First two header values
    00228         iputc(0);  //  must be 0.
    00229
    00230         WbmpPutMultibyte(iCurImage->Width);  // Write the width
    00231         WbmpPutMultibyte(iCurImage->Height); //  and the height.
    00232
    00233         //TempImage = iConvertImage(iCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE);
    00234         if (iGetInt(IL_QUANTIZATION_MODE) == IL_NEU_QUANT)
    00235                 TempImage = iNeuQuant(iCurImage, 2);
    00236         else // Assume IL_WU_QUANT otherwise.
    00237                 TempImage = iQuantizeImage(iCurImage, 2);
    00238
    00239         if (TempImage == NULL)
    00240                 return IL_FALSE;
    00241
    00242         if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) {
    00243                 TempData = iGetFlipped(TempImage);
    00244                 if (TempData == NULL) {
    00245                         ilCloseImage(TempImage);
    00246                         return IL_FALSE;
    00247                 }
    00248         } else {
    00249                 TempData = TempImage->Data;
    00250         }
    00251
    00252         for (i = 0; i < TempImage->Height; i++) {
    00253                 for (j = 0; j < TempImage->Width; j += 8) {
    00254                         Val = 0;
    00255                         for (k = 0; k < 8; k++) {
    00256                                 if (j + k < TempImage->Width) {
    00257                                         //Val |= ((TempData[TempImage->Width * i + j + k] > 0x7F) ? (0x80 >> k) : 0x00);
    00258                                         Val |= ((TempData[TempImage->Width * i + j + k] == 1) ? (0x80 >> k) : 0x00);
    00259                                 }
    00260                         }
    00261                         iputc(Val);
    00262                 }
    00263         }
    00264
    00265         if (TempData != TempImage->Data)
    00266                 ifree(TempData);
    00267         ilCloseImage(TempImage);
    00268
    00269         return IL_TRUE;
    00270 }
    00271
    00272
    00273
    00274 #endif//IL_NO_WBMP
    00275