Example #1
0
/**
Read and decode JPEG-XR Exif-GPS IFD
@param dib Input FIBITMAP
@param profile Pointer to the Exif-GPS profile
@param length Exif-GPS profile length
@param file_offset Reference offset in the original file of each tag value whose length is > 4
@return Returns TRUE if successful, FALSE otherwise
*/
BOOL  
jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) {
	// assume Little Endian order
	BOOL bBigEndian = FALSE;
	
	// process Exif GPS IFD
	return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_GPS);
}
Example #2
0
/**
	Read JPEG_APP1 marker (Exif profile)
	@param dib Input FIBITMAP
	@param dataptr Pointer to the APP1 marker
	@param datalen APP1 marker length
	@return Returns TRUE if successful, FALSE otherwise
*/
BOOL  
jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
    // marker identifying string for Exif = "Exif\0\0"
    BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
	BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 };		// Intel order
	BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A };		// Motorola order

	unsigned int length = datalen;
	BYTE *profile = (BYTE*)dataptr;

	// verify the identifying string

	if(memcmp(exif_signature, profile, sizeof(exif_signature)) == 0) {
		// Exif profile

		profile += sizeof(exif_signature);
		length  -= sizeof(exif_signature);

		// check the endianess order
		
		BOOL bMotorolaOrder = TRUE;

		if(memcmp(profile, lsb_first, sizeof(lsb_first)) == 0) {
			// Exif section in Intel order
			bMotorolaOrder = FALSE;
		} else {
			if(memcmp(profile, msb_first, sizeof(msb_first)) == 0) {
				// Exif section in Motorola order
				bMotorolaOrder = TRUE;
			} else {
				// Invalid Exif alignment marker
				return FALSE;
			}
		}

		// this is the offset to the first IFD
		unsigned long first_offset = ReadUint32(bMotorolaOrder, profile + 4);

		if (first_offset < 8 || first_offset > 16) {
			// This is usually set to 8
			// but PENTAX Optio 230 has it set differently, and uses it as offset. 
			FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value");
			return FALSE;
		}

		// process Exif directories
		return jpeg_read_exif_dir(dib, profile, first_offset, length, bMotorolaOrder);
	}

	return FALSE;
}
Example #3
0
/**
	Read and decode JPEG_APP1 marker (Exif profile)
	@param dib Input FIBITMAP
	@param dataptr Pointer to the APP1 marker
	@param datalen APP1 marker length
	@return Returns TRUE if successful, FALSE otherwise
*/
BOOL
jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
    // marker identifying string for Exif = "Exif\0\0"
    BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
    BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 };		// Intel order
    BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A };		// Motorola order

    unsigned int length = datalen;
    BYTE *profile = (BYTE*)dataptr;

    // verify the identifying string

    if(memcmp(exif_signature, profile, sizeof(exif_signature)) == 0) {
        // Exif profile - TIFF header with 2 IFDs. 0th - the image attributes, 1st - may be used for thumbnail

        profile += sizeof(exif_signature);
        length  -= sizeof(exif_signature);

        // read the TIFF header (8 bytes)

        // check the endianess order

        BOOL bMotorolaOrder = TRUE;

        if(memcmp(profile, lsb_first, sizeof(lsb_first)) == 0) {
            // Exif section in Intel order
            bMotorolaOrder = FALSE;
        } else {
            if(memcmp(profile, msb_first, sizeof(msb_first)) == 0) {
                // Exif section in Motorola order
                bMotorolaOrder = TRUE;
            } else {
                // Invalid Exif alignment marker
                return FALSE;
            }
        }

        // this is the offset to the first IFD (Image File Directory)
        unsigned long first_offset = ReadUint32(bMotorolaOrder, profile + 4);
        if (first_offset > length) {
            // bad Exif data
            return FALSE;
        }

        /*
        Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset
        => tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D
        if (first_offset < 8 || first_offset > 16) {
        	// This is usually set to 8
        	// but PENTAX Optio 230 has it set differently, and uses it as offset.
        	FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value");
        	return FALSE;
        }
        */

        // process Exif directories
        return jpeg_read_exif_dir(dib, profile, first_offset, length, bMotorolaOrder);
    }

    return FALSE;
}
Example #4
0
/**
Read and decode JPEG_APP1 marker (Exif profile)
@param dib Input FIBITMAP
@param data Pointer to the APP1 marker
@param length APP1 marker length
@return Returns TRUE if successful, FALSE otherwise
*/
BOOL  
jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *data, unsigned length) {
    // marker identifying string for Exif = "Exif\0\0"
    BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
	BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 };		// Classic TIFF signature - little-endian order
	BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A };		// Classic TIFF signature - big-endian order

	// profile size is up to 32-bit
	DWORD dwProfileLength = (DWORD)length;
	BYTE *pbProfile = (BYTE*)data;

	// verify the identifying string
	if(memcmp(exif_signature, pbProfile, sizeof(exif_signature)) == 0) {
		// This is an Exif profile
		// should contain a TIFF header with up to 2 IFDs (IFD stands for 'Image File Directory')
		// 0th IFD : the image attributes, 1st IFD : may be used for thumbnail

		pbProfile += sizeof(exif_signature);
		dwProfileLength -= sizeof(exif_signature);

		// read the TIFF header (8 bytes)

		// check the endianess order
		
		BOOL bBigEndian = TRUE;

		if(memcmp(pbProfile, lsb_first, sizeof(lsb_first)) == 0) {
			// Exif section is in little-endian order
			bBigEndian = FALSE;
		} else {
			if(memcmp(pbProfile, msb_first, sizeof(msb_first)) == 0) {
				// Exif section is in big-endian order
				bBigEndian = TRUE;
			} else {
				// Invalid Exif alignment marker
				return FALSE;
			}
		}

		// this is the offset to the first IFD (Image File Directory)
		DWORD dwFirstOffset = ReadUint32(bBigEndian, pbProfile + 4);
		if (dwFirstOffset > dwProfileLength) {
			// bad Exif data
			return FALSE;
		}

		/*
		Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset
		=> tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D
		if (dwFirstOffset < 8 || dwFirstOffset > 16) {
			// This is usually set to 8
			// but PENTAX Optio 230 has it set differently, and uses it as offset. 
			FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value");
			return FALSE;
		}
		*/

		// process Exif directories, starting with Exif-TIFF IFD
		return jpeg_read_exif_dir(dib, pbProfile, dwFirstOffset, dwProfileLength, 0, bBigEndian, TagLib::EXIF_MAIN);
	}

	return FALSE;
}