// Internal function used to load the Pxr. ILboolean iLoadPxrInternal() { ILushort Width, Height; ILubyte Bpp; Width = sizeof(PIXHEAD); iseek(416, IL_SEEK_SET); Height = GetLittleUShort(); Width = GetLittleUShort(); iseek(424, IL_SEEK_SET); Bpp = igetc(); switch (Bpp) { case 0x08: ilTexImage(Width, Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL); break; case 0x0E: ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); break; case 0x0F: ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); break; default: ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } iseek(1024, IL_SEEK_SET); iread(iCurImage->Data, 1, iCurImage->SizeOfData); iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; return IL_TRUE; }
// Internal function used to get the Psp header from the current file. ILboolean iGetPspHead() { if (iread(Header.FileSig, 1, 32) != 32) return IL_FALSE; Header.MajorVersion = GetLittleUShort(); Header.MinorVersion = GetLittleUShort(); return IL_TRUE; }
// Internal function used to load the Gif. ILboolean iLoadGifInternal() { GIFHEAD Header; ILpal GlobalPal; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } GlobalPal.Palette = NULL; GlobalPal.PalSize = 0; //read header iread(&Header.Sig, 1, 6); Header.Width = GetLittleUShort(); Header.Height = GetLittleUShort(); Header.ColourInfo = igetc(); Header.Background = igetc(); Header.Aspect = igetc(); if (!strnicmp(Header.Sig, "GIF87A", 6)) { GifType = GIF87A; } else if (!strnicmp(Header.Sig, "GIF89A", 6)) { GifType = GIF89A; } else { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Check for a global colour map. if (Header.ColourInfo & (1 << 7)) { if (!iGetPalette(Header.ColourInfo, &GlobalPal)) { return IL_FALSE; } } if (!GetImages(&GlobalPal, &Header)) return IL_FALSE; if (GlobalPal.Palette && GlobalPal.PalSize) ifree(GlobalPal.Palette); GlobalPal.Palette = NULL; GlobalPal.PalSize = 0; ilFixImage(); return IL_TRUE; }
// Internal function obtain the .dcx header from the current file. ILboolean iGetDcxHead(DCXHEAD *Head) { Head->Xmin = GetLittleUShort(); Head->Ymin = GetLittleUShort(); Head->Xmax = GetLittleUShort(); Head->Ymax = GetLittleUShort(); Head->HDpi = GetLittleUShort(); Head->VDpi = GetLittleUShort(); Head->Bps = GetLittleUShort(); Head->PaletteInfo = GetLittleUShort(); Head->HScreenSize = GetLittleUShort(); Head->VScreenSize = GetLittleUShort(); return IL_TRUE; }
ILboolean GetUtxHead(UTXHEADER *Header) { Header->Signature = GetLittleUInt(); Header->Version = GetLittleUShort(); Header->LicenseMode = GetLittleUShort(); Header->Flags = GetLittleUInt(); Header->NameCount = GetLittleUInt(); Header->NameOffset = GetLittleUInt(); Header->ExportCount = GetLittleUInt(); Header->ExportOffset = GetLittleUInt(); Header->ImportCount = GetLittleUInt(); Header->ImportOffset = GetLittleUInt(); return IL_TRUE; }
ILboolean SkipElement(DICOMHEAD *Header, ILushort GroupNum, ILushort ElementNum) { ILubyte VR1, VR2; ILuint ValLen; // 2 byte character string telling what type this element is ('OB', 'UI', etc.) VR1 = igetc(); VR2 = igetc(); if ((VR1 == 'O' && VR2 == 'B') || (VR1 == 'O' && VR2 == 'W') || (VR1 == 'O' && VR2 == 'F') || (VR1 == 'S' && VR2 == 'Q') || (VR1 == 'U' && VR2 == 'T') || (VR1 == 'U' && VR2 == 'N')) { // These all have a different format than the other formats, since they can be up to 32 bits long. GetLittleUShort(); // Values reserved, we do not care about them. ValLen = GetInt(Header, GroupNum);//GetLittleUInt(); // Length of the rest of the element if (ValLen % 2) // This length must be even, according to the specs. return IL_FALSE; if (ElementNum != 0x00) // Element numbers of 0 tell the size of the full group, so we do not skip this. // @TODO: We could use this to skip groups that we do not care about. if (iseek(ValLen, IL_SEEK_CUR)) return IL_FALSE; } else { // These have a length of 16 bits. ValLen = GetShort(Header, GroupNum);//GetLittleUShort(); //if (ValLen % 2) // This length must be even, according to the specs. // ValLen++; // Add the extra byte to seek. //if (ElementNum != 0x00) // Element numbers of 0 tell the size of the full group, so we do not skip this. // @TODO: We could use this to skip groups that we do not care about. if (iseek(ValLen, IL_SEEK_CUR)) return IL_FALSE; } return IL_TRUE; }
ILboolean SkipExtensions(GFXCONTROL *Gfx) { ILint Code; ILint Label; ILint Size; // DW (06-03-2002): Apparently there can be... //if (GifType == GIF87A) // return IL_TRUE; // No extensions in the GIF87a format. do { if((Code = igetc()) == IL_EOF) return IL_FALSE; if (Code != 0x21) { iseek(-1, IL_SEEK_CUR); return IL_TRUE; } if((Label = igetc()) == IL_EOF) return IL_FALSE; switch (Label) { case 0xF9: Gfx->Size = igetc(); Gfx->Packed = igetc(); Gfx->Delay = GetLittleUShort(); Gfx->Transparent = igetc(); Gfx->Terminator = igetc(); if (ieof()) return IL_FALSE; Gfx->Used = IL_FALSE; break; /*case 0xFE: break; case 0x01: break;*/ default: do { if((Size = igetc()) == IL_EOF) return IL_FALSE; iseek(Size, IL_SEEK_CUR); } while (!ieof() && Size != 0); } // @TODO: Handle this better. if (ieof()) { ilSetError(IL_FILE_READ_ERROR); return IL_FALSE; } } while (1); return IL_TRUE; }
ILboolean ilisValidTiffFunc() { ILushort Header1, Header2; Header1 = GetLittleUShort(); if (Header1 != MAGIC_HEADER1 && Header1 != MAGIC_HEADER2) return IL_FALSE; if (Header1 == MAGIC_HEADER1) Header2 = GetLittleUShort(); else Header2 = GetBigUShort(); if (Header2 != 42) return IL_FALSE; return IL_TRUE; }
ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes) { ILint count; int i, j, k; ILubyte col[4]; for(i = 0; i < width; i += count) { if (ieof()) return IL_FALSE; count = igetc(); if (count == IL_EOF) return IL_FALSE; if (count >= 128) { // Repeated sequence if (count == 128) { // Long run count = GetLittleUShort(); if (ieof()) return IL_FALSE; } else count -= 127; // We've run past... if ((i + count) > width) { //fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Repeat) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol); return IL_FALSE; } for (j = 0; j < noCol; j++) if (iread(&col[j], 1, 1) != 1) return IL_FALSE; for (k = 0; k < count; k++, scan += bytes) { for (j = 0; j < noCol; j++) scan[off[j]] = col[j]; } } else { // Raw sequence count++; if ((i + count) > width) { //fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Raw) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol); return IL_FALSE; } for (k = count; k > 0; k--, scan += bytes) { for (j = 0; j < noCol; j++) if (iread(&scan[off[j]], 1, 1) != 1) return IL_FALSE; } } } return IL_TRUE; }
ILboolean SkipExtensions(GFXCONTROL *Gfx) { ILint Code; ILint Label; ILint Size; do { if((Code = iCurImage->io.getc(iCurImage->io.handle)) == IL_EOF) return IL_FALSE; if (Code != 0x21) { iCurImage->io.seek(iCurImage->io.handle, -1, IL_SEEK_CUR); return IL_TRUE; } if((Label = iCurImage->io.getc(iCurImage->io.handle)) == IL_EOF) return IL_FALSE; switch (Label) { case 0xF9: Gfx->Size = iCurImage->io.getc(iCurImage->io.handle); Gfx->Packed = iCurImage->io.getc(iCurImage->io.handle); Gfx->Delay = GetLittleUShort(&iCurImage->io); Gfx->Transparent = iCurImage->io.getc(iCurImage->io.handle); Gfx->Terminator = iCurImage->io.getc(iCurImage->io.handle); if (iCurImage->io.eof(iCurImage->io.handle)) return IL_FALSE; Gfx->Used = IL_FALSE; break; /*case 0xFE: break; case 0x01: break;*/ default: do { if((Size = iCurImage->io.getc(iCurImage->io.handle)) == IL_EOF) return IL_FALSE; iCurImage->io.seek(iCurImage->io.handle, Size, IL_SEEK_CUR); } while (!iCurImage->io.eof(iCurImage->io.handle) && Size != 0); } // @TODO: Handle this better. if (iCurImage->io.eof(iCurImage->io.handle)) { ilSetError(IL_FILE_READ_ERROR); return IL_FALSE; } } while (1); return IL_TRUE; }
// Internal function obtain the .pcx header from the current file. ILboolean iGetPcxHead(PCXHEAD *Head) { Head->Manufacturer = igetc(); Head->Version = igetc(); Head->Encoding = igetc(); Head->Bpp = igetc(); Head->Xmin = GetLittleUShort(); Head->Ymin = GetLittleUShort(); Head->Xmax = GetLittleUShort(); Head->Ymax = GetLittleUShort(); Head->HDpi = GetLittleUShort(); Head->VDpi = GetLittleUShort(); iread(Head->ColMap, 1, 48); Head->Reserved = igetc(); Head->NumPlanes = igetc(); Head->Bps = GetLittleUShort(); Head->PaletteInfo = GetLittleUShort(); Head->HScreenSize = GetLittleUShort(); Head->VScreenSize = GetLittleUShort(); iread(Head->Filler, 1, 54); return IL_TRUE; }
ILboolean GetUID(ILubyte *UID) { ILubyte VR1, VR2; ILushort ValLen; // 2 byte character string telling what type this element is ('OB', 'UI', etc.) VR1 = igetc(); VR2 = igetc(); if (VR1 != 'U' || VR2 != 'I') // 'UI' == UID return IL_FALSE; ValLen = GetLittleUShort(); if (iread(UID, ValLen, 1) != 1) return IL_FALSE; UID[64] = 0; // Just to make sure that our string is terminated. return IL_TRUE; }
// Internal function used to get the .bmp header from the current file. ILboolean iGetBmpHead(BMPHEAD * const Header) { Header->bfType = GetLittleUShort(); Header->bfSize = GetLittleInt(); Header->bfReserved = GetLittleUInt(); Header->bfDataOff = GetLittleInt(); Header->biSize = GetLittleInt(); Header->biWidth = GetLittleInt(); Header->biHeight = GetLittleInt(); Header->biPlanes = GetLittleShort(); Header->biBitCount = GetLittleShort(); Header->biCompression = GetLittleInt(); Header->biSizeImage = GetLittleInt(); Header->biXPelsPerMeter = GetLittleInt(); Header->biYPelsPerMeter = GetLittleInt(); Header->biClrUsed = GetLittleInt(); Header->biClrImportant = GetLittleInt(); return IL_TRUE; }
ILboolean ReadAlphaBlock(ILuint BlockLen) { BLOCKHEAD Block; ALPHAINFO_CHUNK AlphaInfo; ALPHA_CHUNK AlphaChunk; ILushort NumAlpha, StringSize; ILuint ChunkSize, Padding; if (Header.MajorVersion == 3) { NumAlpha = GetLittleUShort(); } else { ChunkSize = GetLittleUInt(); NumAlpha = GetLittleUShort(); Padding = (ChunkSize - 4 - 2); if (Padding > 0) iseek(Padding, IL_SEEK_CUR); } // Alpha channel header if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) return IL_FALSE; if (Header.MajorVersion == 3) Block.BlockLen = GetLittleUInt(); else UInt(&Block.BlockLen); if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { return IL_FALSE; } if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK) return IL_FALSE; if (Header.MajorVersion >= 4) { ChunkSize = GetLittleUInt(); StringSize = GetLittleUShort(); iseek(StringSize, IL_SEEK_CUR); if (iread(&AlphaInfo, sizeof(AlphaInfo), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo)); if (Padding > 0) iseek(Padding, IL_SEEK_CUR); ChunkSize = GetLittleUInt(); if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4 - sizeof(AlphaChunk)); if (Padding > 0) iseek(Padding, IL_SEEK_CUR); } else { iseek(256, IL_SEEK_CUR); iread(&AlphaInfo, sizeof(AlphaInfo), 1); if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1) return IL_FALSE; } /*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2); if (Alpha == NULL) { return IL_FALSE; }*/ Alpha = GetChannel(); if (Alpha == NULL) return IL_FALSE; return IL_TRUE; }
ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead) { IMAGEDESC ImageDesc, OldImageDesc; GFXCONTROL Gfx; ILboolean BaseImage = IL_TRUE; ILimage *Image = iCurImage, *TempImage = NULL; ILuint NumImages = 0, i; ILint input; Gfx.Used = IL_TRUE; while (!ieof()) { ILubyte DisposalMethod = 1; i = itell(); if (!SkipExtensions(&Gfx)) goto error_clean; i = itell(); if (!Gfx.Used) DisposalMethod = (Gfx.Packed & 0x1C) >> 2; //read image descriptor ImageDesc.Separator = igetc(); if (ImageDesc.Separator != 0x2C) //end of image break; ImageDesc.OffX = GetLittleUShort(); ImageDesc.OffY = GetLittleUShort(); ImageDesc.Width = GetLittleUShort(); ImageDesc.Height = GetLittleUShort(); ImageDesc.ImageInfo = igetc(); if (ieof()) { ilGetError(); // Gets rid of the IL_FILE_READ_ERROR that inevitably results. break; } if (!BaseImage) { NumImages++; Image->Next = ilNewImage(iCurImage->Width, iCurImage->Height, 1, 1, 1); if (Image->Next == NULL) goto error_clean; //20040612: DisposalMethod controls how the new images data is to be combined //with the old image. 0 means that it doesn't matter how they are combined, //1 means keep the old image, 2 means set to background color, 3 is //load the image that was in place before the current (this is not implemented //here! (TODO?)) if (DisposalMethod == 2 || DisposalMethod == 3) //Note that this is actually wrong, too: If the image has a local //color table, we should really search for the best fit of the //background color table and use that index (?). Furthermore, //we should only memset the part of the image that is not read //later (if we are sure that no parts of the read image are transparent). if (!Gfx.Used && Gfx.Packed & 0x1) memset(Image->Next->Data, Gfx.Transparent, Image->SizeOfData); else memset(Image->Next->Data, GifHead->Background, Image->SizeOfData); else if (DisposalMethod == 1 || DisposalMethod == 0) memcpy(Image->Next->Data, Image->Data, Image->SizeOfData); //Interlacing has to be removed after the image was copied (line above) if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced. if (!RemoveInterlace(Image)) goto error_clean; } Image = Image->Next; Image->Format = IL_COLOUR_INDEX; Image->Origin = IL_ORIGIN_UPPER_LEFT; } else { BaseImage = IL_FALSE; if (!Gfx.Used && Gfx.Packed & 0x1) memset(Image->Data, Gfx.Transparent, Image->SizeOfData); else memset(Image->Data, GifHead->Background, Image->SizeOfData); //memset(Image->Data, GifHead->Background, Image->SizeOfData); } Image->OffX = ImageDesc.OffX; Image->OffY = ImageDesc.OffY; // Check to see if the image has its own palette. if (ImageDesc.ImageInfo & (1 << 7)) { if (!iGetPalette(ImageDesc.ImageInfo, &Image->Pal)) { goto error_clean; } } else { if (!iCopyPalette(&Image->Pal, GlobalPal)) { goto error_clean; } } if (!GifGetData(Image->Data + ImageDesc.OffX + ImageDesc.OffY*Image->Width, Image->SizeOfData, ImageDesc.Width, ImageDesc.Height, Image->Width, &Gfx)) { ilSetError(IL_ILLEGAL_FILE_VALUE); goto error_clean; } // See if there was a valid graphics control extension. if (!Gfx.Used) { Gfx.Used = IL_TRUE; Image->Duration = Gfx.Delay * 10; // We want it in milliseconds. // See if a transparent colour is defined. if (Gfx.Packed & 1) { if (!ConvertTransparent(Image, Gfx.Transparent)) { goto error_clean; } } } i = itell(); // Terminates each block. if((input = igetc()) == IL_EOF) goto error_clean; if (input != 0x00) iseek(-1, IL_SEEK_CUR); // break; OldImageDesc = ImageDesc; } //Deinterlace last image if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced. if (!RemoveInterlace(Image)) goto error_clean; } iCurImage->NumNext = NumImages; if (BaseImage) // Was not able to load any images in... return IL_FALSE; return IL_TRUE; error_clean: Image = iCurImage->Next; while (Image) { TempImage = Image; Image = Image->Next; ilCloseImage(TempImage); } return IL_FALSE; }
static ILboolean ReadLayerBlock(PSP_CTX *ctx) { BLOCKHEAD Block; LAYERINFO_CHUNK LayerInfo; LAYERBITMAP_CHUNK Bitmap; ILuint ChunkSize, Padding, i, j; ILushort NumChars; // Layer sub-block header if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) return IL_FALSE; if (ctx->Header.MajorVersion == 3) { Block.BlockLen = GetLittleUInt(ctx->io); } else { UInt(&Block.BlockLen); } if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { return IL_FALSE; } if (Block.BlockID != PSP_LAYER_BLOCK) return IL_FALSE; if (ctx->Header.MajorVersion == 3) { SIOseek(ctx->io, 256, IL_SEEK_CUR); // We don't care about the name of the layer. SIOread(ctx->io, &LayerInfo, sizeof(LayerInfo), 1); if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1) return IL_FALSE; } else { // ctx->Header.MajorVersion >= 4 ChunkSize = GetLittleUInt(ctx->io); NumChars = GetLittleUShort(ctx->io); SIOseek(ctx->io, NumChars, IL_SEEK_CUR); // We don't care about the layer's name. ChunkSize -= (2 + 4 + NumChars); if (SIOread(ctx->io, &LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1) return IL_FALSE; // Can have new entries in newer versions of the spec (5.0). Padding = (ChunkSize) - sizeof(LayerInfo); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); ChunkSize = GetLittleUInt(ctx->io); if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4) - sizeof(Bitmap); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); } ctx->Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels); if (ctx->Channels == NULL) { return IL_FALSE; } ctx->NumChannels = Bitmap.NumChannels; for (i = 0; i < ctx->NumChannels; i++) { ctx->Channels[i] = GetChannel(ctx); if (ctx->Channels[i] == NULL) { for (j = 0; j < i; j++) ifree(ctx->Channels[j]); return IL_FALSE; } } return IL_TRUE; }
static ILboolean ReadAlphaBlock(PSP_CTX *ctx) { BLOCKHEAD Block; ALPHAINFO_CHUNK AlphaInfo; ALPHA_CHUNK AlphaChunk; ILushort StringSize; ILuint ChunkSize, Padding; if (ctx->Header.MajorVersion == 3) { /* ILuint NumAlpha = */ GetLittleUShort(ctx->io); } else { ChunkSize = GetLittleUInt(ctx->io); /* NumAlpha = */ GetLittleUShort(ctx->io); Padding = (ChunkSize - 4 - 2); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); } // Alpha channel header if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) return IL_FALSE; if (ctx->Header.MajorVersion == 3) { Block.BlockLen = GetLittleUInt(ctx->io); } else { UInt(&Block.BlockLen); } if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 || Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) { return IL_FALSE; } if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK) return IL_FALSE; if (ctx->Header.MajorVersion >= 4) { ChunkSize = GetLittleUInt(ctx->io); StringSize = GetLittleUShort(ctx->io); SIOseek(ctx->io, StringSize, IL_SEEK_CUR); if (SIOread(ctx->io, &AlphaInfo, sizeof(AlphaInfo), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo)); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); ChunkSize = GetLittleUInt(ctx->io); if (SIOread(ctx->io, &AlphaChunk, sizeof(AlphaChunk), 1) != 1) return IL_FALSE; Padding = (ChunkSize - 4 - sizeof(AlphaChunk)); if (Padding > 0) SIOseek(ctx->io, Padding, IL_SEEK_CUR); } else { SIOseek(ctx->io, 256, IL_SEEK_CUR); SIOread(ctx->io, &AlphaInfo, sizeof(AlphaInfo), 1); if (SIOread(ctx->io, &AlphaChunk, sizeof(AlphaChunk), 1) != 1) return IL_FALSE; } /*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2); if (Alpha == NULL) { return IL_FALSE; }*/ ctx->Alpha = GetChannel(ctx); if (ctx->Alpha == NULL) return IL_FALSE; return IL_TRUE; }
// Internal function used to get the DICOM header from the current file. ILboolean iGetDicomHead(DICOMHEAD *Header) { ILushort GroupNum, ElementNum; ILboolean ReachedData = IL_FALSE; ILubyte Var2, UID[65]; // Signature should be "DICM" at position 128. iseek(128, IL_SEEK_SET); if (iread(Header->Signature, 1, 4) != 4) return IL_FALSE; //@TODO: What about the case when we are reading an image with Big Endian data? do { GroupNum = GetGroupNum(Header); ElementNum = GetShort(Header, GroupNum);; switch (GroupNum) { case 0x02: switch (ElementNum) { /*case 0x01: // Version number if (!GetNumericValue(&Header->Version)) return IL_FALSE; if (Header->Version != 0x0100) return IL_FALSE; break;*/ case 0x10: //@TODO: Look at pg. 60 of 07_05pu.pdf (PS 3.5) for more UIDs. if (!GetUID(UID)) return IL_FALSE; if (!strncmp((const char*)UID, "1.2.840.10008.1.2.2", 64)) // Explicit big endian Header->BigEndian = IL_TRUE; else if (!strncmp((const char*)UID, "1.2.840.10008.1.2.1", 64)) // Explicit little endian Header->BigEndian = IL_FALSE; else if (!strncmp((const char*)UID, "1.2.840.10008.1.2", 64)) // Implicit little endian Header->BigEndian = IL_FALSE; else return IL_FALSE; // Unrecognized UID. break; default: if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it. return IL_FALSE; } break; case 0x28: switch (ElementNum) { case 0x02: // Samples per pixel if (!GetNumericValue(Header, GroupNum, &Header->Samples)) return IL_FALSE; break; case 0x08: // Number of frames, or depth if (!GetNumericValue(Header, GroupNum, &Header->Depth)) return IL_FALSE; break; case 0x10: // The number of rows if (!GetNumericValue(Header, GroupNum, &Header->Height)) return IL_FALSE; break; case 0x11: // The number of columns if (!GetNumericValue(Header, GroupNum, &Header->Width)) return IL_FALSE; break; case 0x100: // Bits allocated per sample if (!GetNumericValue(Header, GroupNum, &Header->BitsAllocated)) return IL_FALSE; break; case 0x101: // Bits stored per sample - Do we really need this information? if (!GetNumericValue(Header, GroupNum, &Header->BitsStored)) return IL_FALSE; break; default: if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it. return IL_FALSE; } break; case 0x7FE0: switch (ElementNum) { case 0x10: // This element is the actual pixel data. We are done with the header here. if (igetc() != 'O') // @TODO: Can we assume that this is always 'O'? return IL_FALSE; Var2 = igetc(); if (Var2 != 'B' && Var2 != 'W' && Var2 != 'F') // 'OB', 'OW' and 'OF' accepted for this element. return IL_FALSE; GetLittleUShort(); // Skip the 2 reserved bytes. Header->DataLen = GetInt(Header, GroupNum);//GetLittleUInt(); ReachedData = IL_TRUE; break; default: if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it. return IL_FALSE; } break; default: if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it. return IL_FALSE; } } while (!ieof() && !ReachedData); if (ieof()) return IL_FALSE; // Some DICOM images do not have the depth (number of frames) field. if (Header->Depth == 0) Header->Depth = 1; switch (Header->BitsAllocated) { case 8: Header->Type = IL_UNSIGNED_BYTE; break; case 16: Header->Type = IL_UNSIGNED_SHORT; break; case 32: Header->Type = IL_FLOAT; //@TODO: Is this ever an integer? break; default: //@TODO: Any other types we can deal with? return IL_FALSE; } // Cannot handle more than 4 channels in an image. if (Header->Samples > 4) return IL_FALSE; Header->Format = ilGetFormatBpp(Header->Samples); return IL_TRUE; }