static ILboolean ReadGrey(ILimage* image, PSDHEAD *Head) { ILuint ColorMode, ResourceSize, MiscInfo; ILushort Compressed; ILenum Type; ILubyte * Resources = NULL; SIO * io = &image->io; ILushort ChannelNum; ColorMode = GetBigUInt(io); // Skip over the 'color mode data section' SIOseek(io, ColorMode, IL_SEEK_CUR); ResourceSize = GetBigUInt(io); // Read the 'image resources section' Resources = (ILubyte*)ialloc(ResourceSize); if (Resources == NULL) { return IL_FALSE; } if (SIOread(io, Resources, 1, ResourceSize) != ResourceSize) goto cleanup_error; MiscInfo = GetBigUInt(io); SIOseek(io, MiscInfo, IL_SEEK_CUR); Compressed = GetBigUShort(io); ChannelNum = Head->Channels; Head->Channels = 1; // Temporary to read only one channel...some greyscale .psd files have 2. switch (Head->Depth) { case 8: Type = IL_UNSIGNED_BYTE; break; case 16: Type = IL_UNSIGNED_SHORT; break; default: iSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } if (!iTexImage(image, Head->Width, Head->Height, 1, 1, IL_LUMINANCE, Type, NULL)) goto cleanup_error; if (!PsdGetData(image, Head, image->Data, (ILboolean)Compressed, ChannelNum)) goto cleanup_error; if (!ParseResources(image, ResourceSize, Resources)) goto cleanup_error; ifree(Resources); return IL_TRUE; cleanup_error: ifree(Resources); return IL_FALSE; }
ILboolean ReadCMYK(PSDHEAD *Head) { ILuint ColorMode, ResourceSize, MiscInfo, Size, i, j; ILushort Compressed; ILenum Format, Type; ILubyte *Resources = NULL, *KChannel = NULL; ColorMode = GetBigUInt(); // Skip over the 'color mode data section' iseek(ColorMode, IL_SEEK_CUR); ResourceSize = GetBigUInt(); // Read the 'image resources section' Resources = (ILubyte*)ialloc(ResourceSize); if (Resources == NULL) { return IL_FALSE; } if (iread(Resources, 1, ResourceSize) != ResourceSize) goto cleanup_error; MiscInfo = GetBigUInt(); iseek(MiscInfo, IL_SEEK_CUR); Compressed = GetBigUShort(); switch (Head->Channels) { case 4: Format = IL_RGB; ChannelNum = 4; Head->Channels = 3; break; case 5: Format = IL_RGBA; ChannelNum = 5; Head->Channels = 4; break; default: ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } switch (Head->Depth) { case 8: Type = IL_UNSIGNED_BYTE; break; case 16: Type = IL_UNSIGNED_SHORT; break; default: ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL)) goto cleanup_error; if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) goto cleanup_error; Size = iCurImage->Bpc * iCurImage->Width * iCurImage->Height; KChannel = (ILubyte*)ialloc(Size); if (KChannel == NULL) goto cleanup_error; if (!GetSingleChannel(Head, KChannel, (ILboolean)Compressed)) goto cleanup_error; if (Format == IL_RGB) { for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 3, j++) { iCurImage->Data[i ] = (iCurImage->Data[i ] * KChannel[j]) >> 8; iCurImage->Data[i+1] = (iCurImage->Data[i+1] * KChannel[j]) >> 8; iCurImage->Data[i+2] = (iCurImage->Data[i+2] * KChannel[j]) >> 8; } } else { // IL_RGBA // The KChannel array really holds the alpha channel on this one. for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 4, j++) {
ILboolean ReadRGB(PSDHEAD *Head) { ILuint ColorMode, ResourceSize, MiscInfo; ILushort Compressed; ILenum Format, Type; ILubyte *Resources = NULL; ColorMode = GetBigUInt(); // Skip over the 'color mode data section' iseek(ColorMode, IL_SEEK_CUR); ResourceSize = GetBigUInt(); // Read the 'image resources section' Resources = (ILubyte*)ialloc(ResourceSize); if (Resources == NULL) return IL_FALSE; if (iread(Resources, 1, ResourceSize) != ResourceSize) goto cleanup_error; MiscInfo = GetBigUInt(); iseek(MiscInfo, IL_SEEK_CUR); Compressed = GetBigUShort(); ChannelNum = Head->Channels; if (Head->Channels == 3) { Format = IL_RGB; } else if (Head->Channels == 4) { Format = IL_RGBA; } else if (Head->Channels >= 5) { // Additional channels are accumulated as a single alpha channel, since // if an image does not have a layer set as the "background", but also // has a real alpha channel, there will be 5 channels (or more). Format = IL_RGBA; } else { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } switch (Head->Depth) { case 8: Type = IL_UNSIGNED_BYTE; break; case 16: Type = IL_UNSIGNED_SHORT; break; default: ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } if (!ilTexImage(Head->Width, Head->Height, 1, (Format==IL_RGB) ? 3 : 4, Format, Type, NULL)) goto cleanup_error; if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) goto cleanup_error; if (!ParseResources(ResourceSize, Resources)) goto cleanup_error; ifree(Resources); return IL_TRUE; cleanup_error: ifree(Resources); return IL_FALSE; }
ILboolean ReadIndexed(PSDHEAD *Head) { ILuint ColorMode, ResourceSize, MiscInfo, i, j, NumEnt; ILushort Compressed; ILubyte *Palette = NULL, *Resources = NULL; ColorMode = GetBigUInt(); // Skip over the 'color mode data section' if (ColorMode % 3 != 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } Palette = (ILubyte*)ialloc(ColorMode); if (Palette == NULL) return IL_FALSE; if (iread(Palette, 1, ColorMode) != ColorMode) goto cleanup_error; ResourceSize = GetBigUInt(); // Read the 'image resources section' Resources = (ILubyte*)ialloc(ResourceSize); if (Resources == NULL) { return IL_FALSE; } if (iread(Resources, 1, ResourceSize) != ResourceSize) goto cleanup_error; MiscInfo = GetBigUInt(); if (ieof()) goto cleanup_error; iseek(MiscInfo, IL_SEEK_CUR); Compressed = GetBigUShort(); if (ieof()) goto cleanup_error; if (Head->Channels != 1 || Head->Depth != 8) { ilSetError(IL_FORMAT_NOT_SUPPORTED); goto cleanup_error; } ChannelNum = Head->Channels; if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) goto cleanup_error; iCurImage->Pal.Palette = (ILubyte*)ialloc(ColorMode); if (iCurImage->Pal.Palette == NULL) { goto cleanup_error; } iCurImage->Pal.PalSize = ColorMode; iCurImage->Pal.PalType = IL_PAL_RGB24; NumEnt = iCurImage->Pal.PalSize / 3; for (i = 0, j = 0; i < iCurImage->Pal.PalSize; i += 3, j++) { iCurImage->Pal.Palette[i ] = Palette[j]; iCurImage->Pal.Palette[i+1] = Palette[j+NumEnt]; iCurImage->Pal.Palette[i+2] = Palette[j+NumEnt*2]; } ifree(Palette); Palette = NULL; if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed)) goto cleanup_error; ParseResources(ResourceSize, Resources); ifree(Resources); Resources = NULL; return IL_TRUE; cleanup_error: ifree(Palette); ifree(Resources); return IL_FALSE; }
ILboolean ReadIndexed(ILimage* image, PSDHEAD *Head) { ILuint ColorMode, ResourceSize, MiscInfo, NumEnt; ILushort Compressed; ILubyte *Palette = NULL, *Resources = NULL; ILushort ChannelNum; ColorMode = GetBigUInt(&image->io); // Skip over the 'color mode data section' if (ColorMode % 3 != 0) { il2SetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } Palette = (ILubyte*)ialloc(ColorMode); if (Palette == NULL) return IL_FALSE; if (image->io.read(&image->io, Palette, 1, ColorMode) != ColorMode) goto cleanup_error; ResourceSize = GetBigUInt(&image->io); // Read the 'image resources section' Resources = (ILubyte*)ialloc(ResourceSize); if (Resources == NULL) { return IL_FALSE; } if (image->io.read(&image->io, Resources, 1, ResourceSize) != ResourceSize) goto cleanup_error; MiscInfo = GetBigUInt(&image->io); if (image->io.eof(&image->io)) goto cleanup_error; image->io.seek(&image->io, MiscInfo, IL_SEEK_CUR); Compressed = GetBigUShort(&image->io); if (image->io.eof(&image->io)) goto cleanup_error; if (Head->Channels != 1 || Head->Depth != 8) { il2SetError(IL_FORMAT_NOT_SUPPORTED); goto cleanup_error; } ChannelNum = Head->Channels; if (!il2TexImage(image, Head->Width, Head->Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) goto cleanup_error; if (!image->Pal.use(ColorMode/3, NULL, IL_PAL_RGB24)) { goto cleanup_error; } NumEnt = image->Pal.getNumCols(); for (ILuint j = 0; j < NumEnt; j++) { image->Pal.setRGB(j, Palette[j], Palette[j+NumEnt], Palette[j+NumEnt*2]); } ifree(Palette); Palette = NULL; if (!PsdGetData(image, Head, image->Data, (ILboolean)Compressed, ChannelNum)) goto cleanup_error; ParseResources(image, ResourceSize, Resources); ifree(Resources); Resources = NULL; return IL_TRUE; cleanup_error: ifree(Palette); ifree(Resources); return IL_FALSE; }