// Creates a new ILimage based on the specifications given ILAPI ILimage* ILAPIENTRY ilNewImage(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte Bpc) { ILimage *Image; if (Bpp == 0 || Bpp > 4) { return NULL; } Image = (ILimage*)ialloc(sizeof(ILimage)); if (Image == NULL) { return NULL; } if (!ilInitImage (Image, Width, Height, Depth, Bpp, ilGetFormatBpp(Bpp), ilGetTypeBpc(Bpc), NULL)) { if (Image->Data != NULL) { ifree(Image->Data); } ifree(Image); return NULL; } return Image; }
// 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; }
// Load either a pgm or a ppm ILboolean iLoadPnmInternal() { ILimage *PmImage = NULL; PPMINFO Info; // ILuint LineInc = 0, SmallInc = 0; Info.Type = 0; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } // Find out what type of pgm/ppm this is if (iGetWord() == IL_FALSE) return IL_FALSE; if (SmallBuff[0] != 'P') { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (SmallBuff[1] == '1') { Info.Type = IL_PBM_ASCII; } else if (SmallBuff[1] == '2') { Info.Type = IL_PGM_ASCII; } else if (SmallBuff[1] == '3') { Info.Type = IL_PPM_ASCII; } else if (SmallBuff[1] == '4') { Info.Type = IL_PBM_BINARY; if (IsLump) { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } } else if (SmallBuff[1] == '5') { Info.Type = IL_PGM_BINARY; } else if (SmallBuff[1] == '6') { Info.Type = IL_PPM_BINARY; } else { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Retrieve the width and height if (iGetWord() == IL_FALSE) return IL_FALSE; Info.Width = atoi(SmallBuff); if (Info.Width == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (iGetWord() == IL_FALSE) return IL_FALSE; Info.Height = atoi(SmallBuff); if (Info.Height == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Retrieve the maximum colour component value if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY) { if (iGetWord() == IL_FALSE) return IL_FALSE; if ((Info.MaxColour = atoi(SmallBuff)) == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } } else Info.MaxColour = 1; if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) { if (Info.Type == IL_PGM_ASCII) { if (Info.MaxColour < 256) Info.Bpp = 1; else Info.Bpp = 2; } else Info.Bpp = 1; } else { Info.Bpp = 3; } switch (Info.Type) { case IL_PBM_ASCII: case IL_PGM_ASCII: case IL_PPM_ASCII: PmImage = ilReadAsciiPpm(&Info); break; case IL_PBM_BINARY: PmImage = ilReadBitPbm(&Info); break; case IL_PGM_BINARY: case IL_PPM_BINARY: PmImage = ilReadBinaryPpm(&Info); break; default: return IL_FALSE; } if (PmImage == NULL) { iCurImage->Format = ilGetFormatBpp(iCurImage->Bpp); ilSetError(IL_FILE_READ_ERROR); return IL_FALSE; } // Is this conversion needed? Just 0's and 1's shows up as all black if (Info.Type == IL_PBM_ASCII) { PbmMaximize(PmImage); } if (Info.MaxColour > 255) PmImage->Type = IL_UNSIGNED_SHORT; PmImage->Origin = IL_ORIGIN_UPPER_LEFT; if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) PmImage->Format = IL_LUMINANCE; else PmImage->Format = IL_RGB; PmImage->Origin = IL_ORIGIN_UPPER_LEFT; ilFixImage(); if (PmImage == NULL) return IL_FALSE; return IL_TRUE; }