- Main Page
- Data Structures
- Files

- File List

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

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 05/19/2002 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-IL/src/il_pcd.c
    00008 //
    00009 // Description: Reads from a Kodak PhotoCD (.pcd) file.
    00010 //              Note:  The code here is sloppy - I had to convert it from Pascal,
    00011 //                              which I've never even attempted to read before...enjoy! =)
    00012 //
    00013 //-----------------------------------------------------------------------------
    00014
    00015
    00016 #include "il_internal.h"
    00017 #ifndef IL_NO_PCD
    00018 #include "il_manip.h"
    00019
    00020
    00021 ILboolean iLoadPcdInternal(void);
    00022
    00024 ILboolean ilLoadPcd(ILconst_string FileName)
    00025 {
    00026         ILHANDLE        PcdFile;
    00027         ILboolean       bPcd = IL_FALSE;
    00028
    00029         PcdFile = iopenr(FileName);
    00030         if (PcdFile == NULL) {
    00031                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00032                 return bPcd;
    00033         }
    00034
    00035         bPcd = ilLoadPcdF(PcdFile);
    00036         icloser(PcdFile);
    00037
    00038         return bPcd;
    00039 }
    00040
    00041
    00043 ILboolean ilLoadPcdF(ILHANDLE File)
    00044 {
    00045         ILuint          FirstPos;
    00046         ILboolean       bRet;
    00047
    00048         iSetInputFile(File);
    00049         FirstPos = itell();
    00050         bRet = iLoadPcdInternal();
    00051         iseek(FirstPos, IL_SEEK_SET);
    00052
    00053         return bRet;
    00054 }
    00055
    00056
    00058 ILboolean ilLoadPcdL(const void *Lump, ILuint Size)
    00059 {
    00060         iSetInputLump(Lump, Size);
    00061         return iLoadPcdInternal();
    00062 }
    00063
    00064
    00065 void YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b)
    00066 {
    00067         static const ILdouble c11 = 0.0054980*256;
    00068         static const ILdouble c12 = 0.0000000*256;
    00069         static const ILdouble c13 = 0.0051681*256;
    00070         static const ILdouble c21 = 0.0054980*256;
    00071         static const ILdouble c22 =-0.0015446*256;
    00072         static const ILdouble c23 =-0.0026325*256;
    00073         static const ILdouble c31 = 0.0054980*256;
    00074         static const ILdouble c32 = 0.0079533*256;
    00075         static const ILdouble c33 = 0.0000000*256;
    00076         ILint r1, g1, b1;
    00077
    00078         r1 = (ILint)(c11*Y + c12*(Cb-156) + c13*(Cr-137));
    00079         g1 = (ILint)(c21*Y + c22*(Cb-156) + c23*(Cr-137));
    00080         b1 = (ILint)(c31*Y + c32*(Cb-156) + c33*(Cr-137));
    00081
    00082         if (r1 < 0)
    00083                 *r = 0;
    00084         else if (r1 > 255)
    00085                 *r = 255;
    00086         else
    00087                 *r = r1;
    00088
    00089         if (g1 < 0)
    00090                 *g = 0;
    00091         else if (g1 > 255)
    00092                 *g = 255;
    00093         else
    00094                 *g = g1;
    00095
    00096         if (b1 < 0)
    00097                 *b = 0;
    00098         else if (b1 > 255)
    00099                 *b = 255;
    00100         else
    00101                 *b = b1;
    00102
    00103         return;
    00104 }
    00105
    00106
    00107 ILboolean iLoadPcdInternal()
    00108 {
    00109         ILubyte VertOrientation;
    00110         ILuint  Width, Height, i, Total, x, CurPos = 0;
    00111         ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0;
    00112         ILuint  PicNum;
    00113
    00114         if (iCurImage == NULL) {
    00115                 ilSetError(IL_ILLEGAL_OPERATION);
    00116                 return IL_FALSE;
    00117         }
    00118
    00119         iseek(72, IL_SEEK_CUR);
    00120         if (iread(&VertOrientation, 1, 1) != 1)
    00121                 return IL_FALSE;
    00122
    00123         iseek(-72, IL_SEEK_CUR);  // Can't rewind
    00124
    00125         PicNum = iGetInt(IL_PCD_PICNUM);
    00126
    00127         switch (PicNum)
    00128         {
    00129                 case 0:
    00130                         iseek(0x02000, IL_SEEK_CUR);
    00131                         Width = 192;
    00132                         Height = 128;
    00133                         break;
    00134                 case 1:
    00135                         iseek(0x0b800, IL_SEEK_CUR);
    00136                         Width = 384;
    00137                         Height = 256;
    00138                         break;
    00139                 case 2:
    00140                         iseek(0x30000, IL_SEEK_CUR);
    00141                         Width = 768;
    00142                         Height = 512;
    00143                         break;
    00144                 default:
    00145                         ilSetError(IL_INVALID_PARAM);
    00146                         return IL_FALSE;
    00147         }
    00148
    00149         if (itell() == IL_EOF)  // Supposed to have data here.
    00150                 return IL_FALSE;
    00151
    00152         Y1 = (ILubyte*)ialloc(Width);
    00153         Y2 = (ILubyte*)ialloc(Width);
    00154         CbCr = (ILubyte*)ialloc(Width);
    00155         if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
    00156                 ifree(Y1);
    00157                 ifree(Y2);
    00158                 ifree(CbCr);
    00159                 return IL_FALSE;
    00160         }
    00161
    00162         if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
    00163                 return IL_FALSE;
    00164         }
    00165         iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00166
    00167         Total = Height >> 1;
    00168         for (i = 0; i < Total; i++) {
    00169                 iread(Y1, 1, Width);
    00170                 iread(Y2, 1, Width);
    00171                 if (iread(CbCr, 1, Width) != Width) {  // Only really need to check the last one.
    00172                         ifree(Y1);
    00173                         ifree(Y2);
    00174                         ifree(CbCr);
    00175                         return IL_FALSE;
    00176                 }
    00177
    00178                 for (x = 0; x < Width; x++) {
    00179                         YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
    00180                         iCurImage->Data[CurPos++] = r;
    00181                         iCurImage->Data[CurPos++] = g;
    00182                         iCurImage->Data[CurPos++] = b;
    00183                 }
    00184
    00185                 for (x = 0; x < Width; x++) {
    00186                         YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
    00187                         iCurImage->Data[CurPos++] = r;
    00188                         iCurImage->Data[CurPos++] = g;
    00189                         iCurImage->Data[CurPos++] = b;
    00190                 }
    00191         }
    00192
    00193         ifree(Y1);
    00194         ifree(Y2);
    00195         ifree(CbCr);
    00196
    00197         // Not sure how it is...the documentation is hard to understand
    00198         if ((VertOrientation & 0x3F) != 8)
    00199                 iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00200         else
    00201                 iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
    00202
    00203         ilFixImage();
    00204
    00205         return IL_TRUE;
    00206 }
    00207
    00208
    00209 #endif//IL_NO_PCD