/*-------------------------------------------------------------------- * DESCRIPTION * Return the header for the profile. * * AUTHOR * doro * * DATE CREATED * October 23, 1995 *------------------------------------------------------------------*/ SpStatus_t KSPAPI SpProfileLoadHeader( char *Filename, SpFileProps_t *Props, SpHeader_t FAR *Header) { SpHugeBuffer_t BufferAddress; SpStatus_t Status = SpStatBadProfile; KpFileId FD; char *name; KpUInt32_t Read_OK; KpInt32_t Read_Amount = HEADER_SIZE; KpFileProps_t fileProps; if (!SpIsICCProfile(Filename, Props)) return (SpStatBadProfile); name = Filename; BufferAddress = allocBufferPtr(HEADER_SIZE); if (BufferAddress == NULL) return (SpStatMemory); #if defined (KPMAC) SpCvrtSpFileProps(Props, &fileProps); #endif if (KpFileOpen(name, "r", &fileProps, &FD)) /* 0 = not opened */ { /* Read HEADER_SIZE into Buffer */ Read_OK = KpFileRead(FD, BufferAddress, &Read_Amount); /* Close File */ if (!KpFileClose(FD)) Status = SpStatBadProfile; if (Read_OK) { Status = SpHeaderToPublic(BufferAddress, HEADER_SIZE, Header); } } freeBufferPtr(BufferAddress); return Status; }
/*-------------------------------------------------------------------- * DESCRIPTION * Convert profile file to internal format. * * AUTHOR * lsh * * DATE CREATED * October 18, 1993 *------------------------------------------------------------------*/ SpStatus_t SpProfileLoadFromBufferImp ( SpProfileData_t FAR *ProfileData, char KPHUGE *BaseAddr) { SpStatus_t Status; char KPHUGE *Ptr; KpUInt32_t ProfileSize; KpUInt32_t TagDataHeader; KpUInt32_t Offset; KpUInt32_t Count; KpUInt32_t i; SpTagId_t TagId; KpUInt32_t TagOffset; KpUInt32_t TagSize; /* validate that atleast the first long of the buffer is readable */ if (BaseAddr == NULL) return SpStatBadBuffer; /* get the long, this is the size of the profile data */ Ptr = BaseAddr; ProfileSize = SpGetUInt32 (&Ptr); /* validate that the entire buffer is readable */ if (BaseAddr == NULL) return SpStatBadBuffer; /* convert the header to public form */ Status = SpHeaderToPublic (BaseAddr, ProfileSize, &ProfileData->Header); if (SpStatSuccess != Status) return Status; TagDataHeader = 128; Ptr = BaseAddr + TagDataHeader; /* check that the offset to the Tag Data is inside the file */ if (ProfileSize < TagDataHeader + 4) return SpStatOutOfRange; /* get number of tags */ Offset = TagDataHeader + sizeof (KpUInt32_t); if (ProfileSize < Offset) return SpStatBadProfile; Ptr = BaseAddr + TagDataHeader; Count = SpGetUInt32 (&Ptr); /* validate that tag directory is readable */ if (ProfileSize < Offset + Count * 3 * sizeof (KpUInt32_t)) Status = SpStatBadProfileDir; /* Set the Profile Size and initialize the Profile Changed Flag */ ProfileData->ProfileSize = ProfileSize; ProfileData->ProfChanged = KPFALSE; /* build tag directory */ Status = SpStatSuccess; for (i = 0; (SpStatSuccess == Status) && (i < Count); i++) { TagId = (SpTagId_t) SpGetUInt32 (&Ptr); TagOffset = SpGetUInt32 (&Ptr); if (ProfileSize < TagOffset) return SpStatBadProfileDir; /* The following two lines are removed to allow for reading of certain ICC Profiles that don't meet the specification. This has been a continual support problem and we've decided to go with the other CMM vendors and loosen our criteria */ /* if (TagOffset & 3) return SpStatBadProfileDir; */ TagSize = SpGetUInt32 (&Ptr); /* Casting one of the items of the sum to the 64-bit type to * force the whole expression be calculated in 64-bit. That * protects the check from overflowing */ if (ProfileSize < (jlong)TagOffset + TagSize) return SpStatBadProfileDir; Status = SpTagDirEntryAdd (ProfileData, TagId, TagSize, BaseAddr + TagOffset); } return Status; }