コード例 #1
0
ファイル: Exif.cpp プロジェクト: Ali-il/gamekit
/**
	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;
}
コード例 #2
0
      /// ctor; parses event data
      CameraEventData(prVoid* pEventData)
         :m_uiEventCode(0)
      {
         BYTE* pbData = reinterpret_cast<BYTE*>(pEventData);

         std::vector<BYTE>& vecBuffer = GetBuffer();
         vecBuffer.assign(pbData, pbData + 12);// at least 12 bytes

         // read length of event data
         prUInt32 uiLength = ReadUint32();

         vecBuffer.assign(pbData, pbData + uiLength);

         unsigned int uiNumParams = (uiLength - 12) / 4;
         Parse(uiNumParams);
      }
コード例 #3
0
int32_t UnpackSavedataBin(EdpPacket* pkg, cJSON** desc_obj,
                          uint8_t** bin_data, uint32_t* bin_len)
{
    int8_t* desc_str;
    if (ReadStr(pkg, &desc_str))
        return ERR_UNPACK_SAVED_BIN_DESC;
    *desc_obj = cJSON_Parse((const char *)desc_str);
    free(desc_str);
    if (*desc_obj == 0)
        return ERR_UNPACK_SAVED_PARSEDESC;
    if (ReadUint32(pkg, bin_len))
        return ERR_UNPACK_SAVED_BINLEN;
    if (ReadBytes(pkg, bin_data, *bin_len))
        return ERR_UNPACK_SAVED_BINDATA;
    my_assert(pkg->_read_pos == pkg->_write_pos);
    return 0;
}
コード例 #4
0
ファイル: Exif.cpp プロジェクト: Antranilan/Sparky
/**
Process a IFD offset
Returns the offset and the metadata model for this tag
*/
static void 
processIFDOffset(FITAG *tag, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
	// get the IFD offset
	*subdirOffset = ReadUint32(msb_order, pval);

	// select a tag info table
	switch(FreeImage_GetTagID(tag)) {
		case TAG_EXIF_OFFSET:
			*md_model = TagLib::EXIF_EXIF;
			break;
		case TAG_GPS_OFFSET:
			*md_model = TagLib::EXIF_GPS;
			break;
		case TAG_INTEROP_OFFSET:
			*md_model = TagLib::EXIF_INTEROP;
			break;
	}
}
コード例 #5
0
ファイル: ReadNTLM.cpp プロジェクト: lofter2011/Icefox
static void
ReadType1MsgBody(const PRUint8 *inBuf, PRUint32 start)
{
    const PRUint8 *cursor = inBuf + start;
    PRUint32 flags;

    PrintBuf("flags", cursor, 4);
    // read flags
    flags = ReadUint32(cursor);
    PrintFlags(flags);

    // type 1 message may not include trailing security buffers
    if ((flags & kNegotiateDomainSupplied) |
            (flags & kNegotiateWorkstationSupplied))
    {
        SecBuf secbuf;
        ReadSecBuf(&secbuf, cursor);
        PrintBuf("supplied domain", inBuf + secbuf.offset, secbuf.length);

        ReadSecBuf(&secbuf, cursor);
        PrintBuf("supplied workstation", inBuf + secbuf.offset, secbuf.length);
    }
}
コード例 #6
0
int32_t UnpackCmdReq(EdpPacket* pkg, int8_t** cmdid, uint16_t* cmdid_len,
                     int8_t** req, uint32_t* req_len)
{
    uint32 remainlen;
    int32_t rc;
    if (ReadRemainlen(pkg, &remainlen))
        return ERR_UNPACK_CMDREQ;

    rc = ReadUint16(pkg, cmdid_len);
    if (rc)
        return rc;
    if (ReadBytes(pkg, (uint8_t**)cmdid, *cmdid_len))
        return ERR_UNPACK_CMDREQ;

    rc = ReadUint32(pkg, req_len);
    if (rc)
        return rc;
    if (ReadBytes(pkg, (uint8_t**)req, *req_len))
        return ERR_UNPACK_CMDREQ;

    my_assert(pkg->_read_pos == pkg->_write_pos);
    return 0;
}
コード例 #7
0
ファイル: oldloader.cpp プロジェクト: benjeffery/openttd
/**
 *
 * Loads a chunk from the old savegame
 *
 */
bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
{
	byte *base_ptr = (byte*)base;

	for (const OldChunks *chunk = chunks; chunk->type != OC_END; chunk++) {
		if (((chunk->type & OC_TTD) && _savegame_type == SGT_TTO) ||
				((chunk->type & OC_TTO) && _savegame_type != SGT_TTO)) {
			/* TTD(P)-only chunk, but TTO savegame || TTO-only chunk, but TTD/TTDP savegame */
			continue;
		}

		byte *ptr = (byte*)chunk->ptr;
		if (chunk->type & OC_DEREFERENCE_POINTER) ptr = *(byte**)ptr;

		for (uint i = 0; i < chunk->amount; i++) {
			/* Handle simple types */
			if (GetOldChunkType(chunk->type) != 0) {
				switch (GetOldChunkType(chunk->type)) {
					/* Just read the byte and forget about it */
					case OC_NULL: ReadByte(ls); break;

					case OC_CHUNK:
						/* Call function, with 'i' as parameter to tell which item we
						 * are going to read */
						if (!chunk->proc(ls, i)) return false;
						break;

					case OC_ASSERT:
						DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
						if (ls->total_read != chunk->offset + _bump_assert_value) throw std::exception();
					default: break;
				}
			} else {
				uint64 res = 0;

				/* Reading from the file: bits 16 to 23 have the FILE type */
				switch (GetOldChunkFileType(chunk->type)) {
					case OC_FILE_I8:  res = (int8)ReadByte(ls); break;
					case OC_FILE_U8:  res = ReadByte(ls); break;
					case OC_FILE_I16: res = (int16)ReadUint16(ls); break;
					case OC_FILE_U16: res = ReadUint16(ls); break;
					case OC_FILE_I32: res = (int32)ReadUint32(ls); break;
					case OC_FILE_U32: res = ReadUint32(ls); break;
					default: NOT_REACHED();
				}

				/* When both pointers are NULL, we are just skipping data */
				if (base_ptr == NULL && chunk->ptr == NULL) continue;

				/* Writing to the var: bits 8 to 15 have the VAR type */
				if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;

				/* Write the data */
				switch (GetOldChunkVarType(chunk->type)) {
					case OC_VAR_I8: *(int8  *)ptr = GB(res, 0, 8); break;
					case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break;
					case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break;
					case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break;
					case OC_VAR_I32:*(int32 *)ptr = res; break;
					case OC_VAR_U32:*(uint32*)ptr = res; break;
					case OC_VAR_I64:*(int64 *)ptr = res; break;
					case OC_VAR_U64:*(uint64*)ptr = res; break;
					default: NOT_REACHED();
				}

				/* Increase pointer base for arrays when looping */
				if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
			}
		}
	}

	return true;
}
コード例 #8
0
ファイル: Exif.cpp プロジェクト: MrLobo/El-Rayo-de-Zeus
/**
	Process Exif directory

	@param dib Input FIBITMAP
	@param tiffp Pointer to the TIFF header
	@param offset 0th IFD offset
	@param length Length of the datafile
	@param msb_order Endianess order of the datafile
	@return 
*/
static BOOL 
jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) {
	WORD de, nde;

	std::stack<WORD>			destack;	// directory entries stack
	std::stack<BYTE*>			ifdstack;	// IFD stack
	std::stack<TagLib::MDMODEL>	modelstack; // metadata model stack

	// Keep a list of already visited IFD to avoid stack overflows 
	// when recursive/cyclic directory structures exist. 
	// This kind of recursive Exif file was encountered with Kodak images coming from 
	// KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W
	std::map<DWORD, int> visitedIFD;

    #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry))

	// set the metadata model to Exif

	TagLib::MDMODEL md_model = TagLib::EXIF_MAIN;

	// set the pointer to the first IFD and follow it were it leads.

	BYTE *ifdp = (BYTE*)tiffp + offset;

	de = 0;

	do {
		// if there is anything on the stack then pop it off
		if(!destack.empty()) {
			ifdp		= ifdstack.top();	ifdstack.pop();
			de			= destack.top();	destack.pop();
			md_model	= modelstack.top();	modelstack.pop();
		}

		// remember that we've visited this directory so that we don't visit it again later
		DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de );
		if(visitedIFD.find(visited) != visitedIFD.end()) {
			continue;
		} else {
			visitedIFD[visited] = 1;	// processed
		}

		// determine how many entries there are in the current IFD
		nde = ReadUint16(msb_order, ifdp);

		for(; de < nde; de++) {
			char *pde = NULL;	// pointer to the directory entry
			char *pval = NULL;	// pointer to the tag value
			
			// create a tag
			FITAG *tag = FreeImage_CreateTag();
			if(!tag) return FALSE;

			// point to the directory entry
			pde = (char*) DIR_ENTRY_ADDR(ifdp, de);

			// get the tag ID
			FreeImage_SetTagID(tag, ReadUint16(msb_order, pde));
			// get the tag format
			WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2);
            if((tag_type - 1) >= EXIF_NUM_FORMATS) {
                // a problem occured : delete the tag (not free'd after)
			    FreeImage_DeleteTag(tag);
				// break out of the for loop
				break;
            }
			FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type);

			// get number of components
			FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4));
			// get the size of the tag value in bytes
			FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * FreeImage_TagDataWidth((WORD)FreeImage_GetTagType(tag)));

			if(FreeImage_GetTagLength(tag) <= 4) {
				// 4 bytes or less and value is in the dir entry itself
				pval = pde + 8;
			} else {
				// if its bigger than 4 bytes, the directory entry contains an offset
				// first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data
				DWORD offset_value = ReadUint32(msb_order, pde + 8);
				if(offset_value > length) {
					// a problem occured : delete the tag (not free'd after)
					FreeImage_DeleteTag(tag);
					// jump to next entry
					continue;
				}
				// now check if offset + tag length exceeds buffer
				if(offset_value > length - FreeImage_GetTagLength(tag)) {
					// a problem occured : delete the tag (not free'd after)
					FreeImage_DeleteTag(tag);
					// jump to next entry
					continue;
				}
				pval = (char*)(tiffp + offset_value);
			}

			// check for a IFD offset
			BOOL isIFDOffset = FALSE;
			switch(FreeImage_GetTagID(tag)) {
				case TAG_EXIF_OFFSET:
				case TAG_GPS_OFFSET:
				case TAG_INTEROP_OFFSET:
				case TAG_MAKER_NOTE:
					isIFDOffset = TRUE;
					break;
			}
			if(isIFDOffset)	{
				DWORD sub_offset = 0;
				TagLib::MDMODEL next_mdmodel = md_model;
				BYTE *next_ifd = ifdp;
				
				// get offset and metadata model
				if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) {
					processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel);
					next_ifd = (BYTE*)pval + sub_offset;
				} else {
					processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel);
					next_ifd = (BYTE*)tiffp + sub_offset;
				}

				if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) {
					// push our current directory state onto the stack
					ifdstack.push(ifdp);
					// bump to the next entry
					de++;
					destack.push(de);

					// push our current metadata model
					modelstack.push(md_model);

					// push new state onto of stack to cause a jump
					ifdstack.push(next_ifd);
					destack.push(0);

					// select a new metadata model
					modelstack.push(next_mdmodel);
					
					// delete the tag as it won't be stored nor deleted in the for() loop
					FreeImage_DeleteTag(tag);
					
					break; // break out of the for loop
				}
				else {
					// unsupported camera model, canon maker tag or or something unknown
					// process as a standard tag
					processExifTag(dib, tag, pval, msb_order, md_model);
				}			

			} else {
				// process as a standard tag
				processExifTag(dib, tag, pval, msb_order, md_model);
			}
			
			// delete the tag
			FreeImage_DeleteTag(tag);

        } // for(nde)

		// additional thumbnail data is skipped

    } while (!destack.empty()); 


	return TRUE;
}
コード例 #9
0
ファイル: Exif.cpp プロジェクト: MrLobo/El-Rayo-de-Zeus
/**
Process a standard Exif tag
*/
static void 
processExifTag(FIBITMAP *dib, FITAG *tag, char *pval, BOOL msb_order, TagLib::MDMODEL md_model) {
	char defaultKey[16];
	int n;
	DWORD i;

	// allocate a buffer to store the tag value
	BYTE *exif_value = (BYTE*)malloc(FreeImage_GetTagLength(tag) * sizeof(BYTE));
	memset(exif_value, 0, FreeImage_GetTagLength(tag) * sizeof(BYTE));

	// get the tag value
	switch(FreeImage_GetTagType(tag)) {

		case FIDT_SHORT:
		{
			WORD *value = (WORD*)&exif_value[0];
			for(i = 0; i < FreeImage_GetTagCount(tag); i++) {
				value[i] = ReadUint16(msb_order, pval + i * sizeof(WORD));
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_SSHORT:
		{
			short *value = (short*)&exif_value[0];
			for(i = 0; i < FreeImage_GetTagCount(tag); i++) {
				value[i] = ReadInt16(msb_order, pval + i * sizeof(short));
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_LONG:
		{
			DWORD *value = (DWORD*)&exif_value[0];
			for(i = 0; i < FreeImage_GetTagCount(tag); i++) {
				value[i] = ReadUint32(msb_order, pval + i * sizeof(DWORD));
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_SLONG:
		{
			LONG *value = (LONG*)&exif_value[0];
			for(i = 0; i < FreeImage_GetTagCount(tag); i++) {
				value[i] = ReadInt32(msb_order, pval + i * sizeof(LONG));
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_RATIONAL:
		{
			n = sizeof(DWORD);

			DWORD *value = (DWORD*)&exif_value[0];						
			for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) {
				// read a sequence of (numerator, denominator)
				value[i] = ReadUint32(msb_order, n*i + (char*)pval);
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_SRATIONAL:
		{
			n = sizeof(LONG);

			LONG *value = (LONG*)&exif_value[0];
			for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) {
				// read a sequence of (numerator, denominator)
				value[i] = ReadInt32(msb_order, n*i + (char*)pval);
			}
			FreeImage_SetTagValue(tag, value);
			break;
		}
		case FIDT_BYTE:
		case FIDT_ASCII:
		case FIDT_SBYTE:
		case FIDT_UNDEFINED:
		case FIDT_FLOAT:
		case FIDT_DOUBLE:
		default:
			FreeImage_SetTagValue(tag, pval);
			break;
	}

	if(md_model == TagLib::EXIF_MAKERNOTE_CANON) {
		// A single Canon tag can have multiple values within
		processCanonMakerNoteTag(dib, tag);
	}
	else {
		TagLib& s = TagLib::instance();

		WORD tag_id = FreeImage_GetTagID(tag);

		// get the tag key and description
		const char *key = s.getTagFieldName(md_model, tag_id, defaultKey);
		FreeImage_SetTagKey(tag, key);
		const char *description = s.getTagDescription(md_model, tag_id);
		FreeImage_SetTagDescription(tag, description);

		// store the tag
		if(key) {
			FreeImage_SetMetadata(s.getFreeImageModel(md_model), dib, key, tag);
		}
	}
	

	// free the temporary buffer
	free(exif_value);

}
コード例 #10
0
ファイル: Exif.cpp プロジェクト: MrLobo/El-Rayo-de-Zeus
/**
Process a maker note IFD offset
Returns the offset and the metadata model for this tag
*/
static void 
processMakerNote(FIBITMAP *dib, char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) {
	FITAG *tagMake = NULL;

	*subdirOffset = 0;
	*md_model = TagLib::UNKNOWN;

	// Determine the camera model and makernote format
	// WARNING: note that Maker may be NULL sometimes so check its value before using it
	// (NULL pointer checking is done by FreeImage_strnicmp)
	FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "Make", &tagMake);
	const char *Maker = (char*)FreeImage_GetTagValue(tagMake);

	if((strncmp("OLYMP\x00\x01", pval, 7) == 0) || (strncmp("OLYMP\x00\x02", pval, 7) == 0) || (strncmp("EPSON", pval, 5) == 0) || (strncmp("AGFA", pval, 4) == 0)) {
		// Olympus Type 1 Makernote
		// Epson and Agfa use Olympus maker note standard, 
		// see: http://www.ozhiker.com/electronics/pjmt/jpeg_info/
		*md_model = TagLib::EXIF_MAKERNOTE_OLYMPUSTYPE1;
		*subdirOffset = 8;
	} 
	else if(strncmp("OLYMPUS\x00\x49\x49\x03\x00", pval, 12) == 0) {
		// Olympus Type 2 Makernote
		// !!! NOT YET SUPPORTED !!!
		*subdirOffset = 0;
		*md_model = TagLib::UNKNOWN;
	}
	else if(strncmp("Nikon", pval, 5) == 0) {
		/* There are two scenarios here:
		 * Type 1:
		 * :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon...........
		 * :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................
		 * Type 3:
		 * :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*...
		 * :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200
		 */
		if (pval[6] == 1) {
			// Nikon type 1 Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE1;
			*subdirOffset = 8;
        } else if (pval[6] == 2) {
            // Nikon type 3 Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE3;
			*subdirOffset = 18;
        } else {
			// Unsupported makernote data ignored
			*md_model = TagLib::UNKNOWN;
		}
	} else if(Maker && (FreeImage_strnicmp("NIKON", Maker, 5) == 0)) {
		// Nikon type 2 Makernote
		*md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE2;
		*subdirOffset = 0;
    } else if(Maker && (FreeImage_strnicmp("Canon", Maker, 5) == 0)) {
        // Canon Makernote
		*md_model = TagLib::EXIF_MAKERNOTE_CANON;
		*subdirOffset = 0;		
    } else if(Maker && (FreeImage_strnicmp("Casio", Maker, 5) == 0)) {
        // Casio Makernote
		if(strncmp("QVC\x00\x00\x00", pval, 6) == 0) {
			// Casio Type 2 Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE2;
			*subdirOffset = 6;
		} else {
			// Casio Type 1 Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE1;
			*subdirOffset = 0;
		}
	} else if ((strncmp("FUJIFILM", pval, 8) == 0) || (Maker && (FreeImage_strnicmp("Fujifilm", Maker, 8) == 0))) {
        // Fujifile Makernote
		// Fujifilm's Makernote always use Intel order altough the Exif section maybe in Intel order or in Motorola order. 
		// If msb_order == TRUE, the Makernote won't be read: 
		// the value of ifdStart will be 0x0c000000 instead of 0x0000000c and the MakerNote section will be discarded later
		// in jpeg_read_exif_dir because the IFD is too high
		*md_model = TagLib::EXIF_MAKERNOTE_FUJIFILM;
        DWORD ifdStart = (DWORD) ReadUint32(msb_order, pval + 8);
		*subdirOffset = ifdStart;
    }
	else if(memcmp("KYOCERA            \x00\x00\x00", pval, 22) == 0) {
		*md_model = TagLib::EXIF_MAKERNOTE_KYOCERA;
		*subdirOffset = 22;
	}
	else if(Maker && (FreeImage_strnicmp("Minolta", Maker, 7) == 0)) {
		// Minolta maker note
		*md_model = TagLib::EXIF_MAKERNOTE_MINOLTA;
		*subdirOffset = 0;
	}
	else if(memcmp("Panasonic\x00\x00\x00", pval, 12) == 0) {
		// Panasonic maker note
		*md_model = TagLib::EXIF_MAKERNOTE_PANASONIC;
		*subdirOffset = 12;
	}
	else if(Maker && ((FreeImage_strnicmp("Pentax", Maker, 6) == 0) || (FreeImage_strnicmp("Asahi", Maker, 5) == 0))) {
		// Pentax maker note
		if(strncmp("AOC\x00", pval, 4) == 0) {
			// Type 2 Pentax Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_PENTAX;
			*subdirOffset = 6;
		} else {
			// Type 1 Pentax Makernote
			*md_model = TagLib::EXIF_MAKERNOTE_ASAHI;
			*subdirOffset = 0;
		}
	}	
	else if((strncmp("SONY CAM", pval, 8) == 0) || (strncmp("SONY DSC", pval, 8) == 0)) {
		*md_model = TagLib::EXIF_MAKERNOTE_SONY;
		*subdirOffset = 12;
	}
}
コード例 #11
0
ファイル: Exif.cpp プロジェクト: 0xmono/miranda-ng
/**
	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;
}
コード例 #12
0
ファイル: Exif.cpp プロジェクト: 0xmono/miranda-ng
/**
	Process Exif directory

	@param dib Input FIBITMAP
	@param tiffp Pointer to the TIFF header
	@param offset 0th IFD offset
	@param length Length of the datafile
	@param msb_order Endianess order of the datafile
	@return
*/
static BOOL
jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) {
    WORD de, nde;

    std::stack<WORD>			destack;	// directory entries stack
    std::stack<const BYTE*>		ifdstack;	// IFD stack
    std::stack<TagLib::MDMODEL>	modelstack; // metadata model stack

    // Keep a list of already visited IFD to avoid stack overflows
    // when recursive/cyclic directory structures exist.
    // This kind of recursive Exif file was encountered with Kodak images coming from
    // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W
    std::map<DWORD, int> visitedIFD;

    /*
    "An Image File Directory (IFD) consists of a 2-byte count of the number of directory
    entries (i.e. the number of fields), followed by a sequence of 12-byte field
    entries, followed by a 4-byte offset of the next IFD (or 0 if none)."
    The "next IFD" (1st IFD) is the thumbnail.
    */
#define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry))

    // set the metadata model to Exif

    TagLib::MDMODEL md_model = TagLib::EXIF_MAIN;

    // set the pointer to the first IFD (0th IFD) and follow it were it leads.

    const BYTE *ifd0th = (BYTE*)tiffp + offset;

    const BYTE *ifdp = ifd0th;

    de = 0;

    do {
        // if there is anything on the stack then pop it off
        if(!destack.empty()) {
            ifdp		= ifdstack.top();
            ifdstack.pop();
            de			= destack.top();
            destack.pop();
            md_model	= modelstack.top();
            modelstack.pop();
        }

        // remember that we've visited this directory and entry so that we don't visit it again later
        DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de );
        if(visitedIFD.find(visited) != visitedIFD.end()) {
            continue;
        } else {
            visitedIFD[visited] = 1;	// processed
        }

        // determine how many entries there are in the current IFD
        nde = ReadUint16(msb_order, ifdp);

        for(; de < nde; de++) {
            char *pde = NULL;	// pointer to the directory entry
            char *pval = NULL;	// pointer to the tag value

            // create a tag
            FITAG *tag = FreeImage_CreateTag();
            if(!tag) return FALSE;

            // point to the directory entry
            pde = (char*) DIR_ENTRY_ADDR(ifdp, de);

            // get the tag ID
            FreeImage_SetTagID(tag, ReadUint16(msb_order, pde));
            // get the tag type
            WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2);
            if((tag_type - 1) >= EXIF_NUM_FORMATS) {
                // a problem occured : delete the tag (not free'd after)
                FreeImage_DeleteTag(tag);
                // break out of the for loop
                break;
            }
            FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type);

            // get number of components
            FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4));
            // check that tag length (size of the tag value in bytes) will fit in a DWORD
            unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag));
            if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) {
                FreeImage_DeleteTag(tag);
                // jump to next entry
                continue;
            }
            FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * tag_data_width);

            if(FreeImage_GetTagLength(tag) <= 4) {
                // 4 bytes or less and value is in the dir entry itself
                pval = pde + 8;
            } else {
                // if its bigger than 4 bytes, the directory entry contains an offset
                // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data
                DWORD offset_value = ReadUint32(msb_order, pde + 8);
                if(offset_value > length) {
                    // a problem occured : delete the tag (not free'd after)
                    FreeImage_DeleteTag(tag);
                    // jump to next entry
                    continue;
                }
                // now check that length does not exceed the buffer size
                if(FreeImage_GetTagLength(tag) > length - offset_value) {
                    // a problem occured : delete the tag (not free'd after)
                    FreeImage_DeleteTag(tag);
                    // jump to next entry
                    continue;
                }
                pval = (char*)(tiffp + offset_value);
            }

            // check for a IFD offset
            BOOL isIFDOffset = FALSE;
            switch(FreeImage_GetTagID(tag)) {
            case TAG_EXIF_OFFSET:
            case TAG_GPS_OFFSET:
            case TAG_INTEROP_OFFSET:
            case TAG_MAKER_NOTE:
                isIFDOffset = TRUE;
                break;
            }
            if(isIFDOffset)	{
                DWORD sub_offset = 0;
                TagLib::MDMODEL next_mdmodel = md_model;
                const BYTE *next_ifd = ifdp;

                // get offset and metadata model
                if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) {
                    processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel);
                    next_ifd = (BYTE*)pval + sub_offset;
                } else {
                    processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel);
                    next_ifd = (BYTE*)tiffp + sub_offset;
                }

                if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) {
                    // push our current directory state onto the stack
                    ifdstack.push(ifdp);
                    // bump to the next entry
                    de++;
                    destack.push(de);

                    // push our current metadata model
                    modelstack.push(md_model);

                    // push new state onto of stack to cause a jump
                    ifdstack.push(next_ifd);
                    destack.push(0);

                    // select a new metadata model
                    modelstack.push(next_mdmodel);

                    // delete the tag as it won't be stored nor deleted in the for() loop
                    FreeImage_DeleteTag(tag);

                    break; // break out of the for loop
                }
                else {
                    // unsupported camera model, canon maker tag or something unknown
                    // process as a standard tag
                    processExifTag(dib, tag, pval, msb_order, md_model);
                }

            } else {
                // process as a standard tag
                processExifTag(dib, tag, pval, msb_order, md_model);
            }

            // delete the tag
            FreeImage_DeleteTag(tag);

        } // for(nde)

        // additional thumbnail data is skipped

    } while (!destack.empty());

    //
    // --- handle thumbnail data ---
    //

    const WORD entriesCount0th = ReadUint16(msb_order, ifd0th);

    DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th));
    if((next_offset == 0) || (next_offset >= length)) {
        return TRUE; //< no thumbnail
    }

    const BYTE* const ifd1st = (BYTE*)tiffp + next_offset;
    const WORD entriesCount1st = ReadUint16(msb_order, ifd1st);

    unsigned thCompression = 0;
    unsigned thOffset = 0;
    unsigned thSize = 0;

    for(int e = 0; e < entriesCount1st; e++) {

        // point to the directory entry
        const BYTE* base = DIR_ENTRY_ADDR(ifd1st, e);

        // check for buffer overflow
        const size_t remaining = (size_t)base + 12 - (size_t)tiffp;
        if(remaining >= length) {
            // bad IFD1 directory, ignore it
            return FALSE;
        }

        // get the tag ID
        WORD tag = ReadUint16(msb_order, base);
        // get the tag type
        WORD type = ReadUint16(msb_order, base + sizeof(WORD));
        // get number of components
        DWORD count = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD));
        // get the tag value
        DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD));

        switch(tag) {
        case TAG_COMPRESSION:
            // Tiff Compression Tag (should be COMPRESSION_OJPEG (6), but is not always respected)
            thCompression = offset;
            break;
        case TAG_JPEG_INTERCHANGE_FORMAT:
            // Tiff JPEGInterchangeFormat Tag
            thOffset = offset;
            break;
        case TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
            // Tiff JPEGInterchangeFormatLength Tag
            thSize = offset;
            break;
        // ### X and Y Resolution ignored, orientation ignored
        case TAG_X_RESOLUTION:		// XResolution
        case TAG_Y_RESOLUTION:		// YResolution
        case TAG_RESOLUTION_UNIT:	// ResolutionUnit
        case TAG_ORIENTATION:		// Orientation
            break;
        default:
            break;
        }
    }

    if(/*thCompression != 6 ||*/ thOffset == 0 || thSize == 0) {
        return TRUE;
    }

    if(thOffset + thSize > length) {
        return TRUE;
    }

    // load the thumbnail

    const BYTE *thLocation = tiffp + thOffset;

    FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(thLocation), thSize);
    FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem);
    FreeImage_CloseMemory(hmem);

    // store the thumbnail
    FreeImage_SetThumbnail(dib, thumbnail);
    // then delete it
    FreeImage_Unload(thumbnail);

    return TRUE;
}
コード例 #13
0
ファイル: Exif.cpp プロジェクト: Antranilan/Sparky
/**
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;
}
コード例 #14
0
static nsresult
ParseType2Msg(const void *inBuf, uint32_t inLen, Type2Msg *msg)
{
  // make sure inBuf is long enough to contain a meaningful type2 msg.
  //
  // 0  NTLMSSP Signature
  // 8  NTLM Message Type
  // 12 Target Name
  // 20 Flags
  // 24 Challenge
  // 32 targetInfo
  // 48 start of optional data blocks
  //
  if (inLen < NTLM_TYPE2_HEADER_LEN)
    return NS_ERROR_UNEXPECTED;

  const uint8_t *cursor = reinterpret_cast<const uint8_t*>(inBuf);

  // verify NTLMSSP signature
  if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0)
    return NS_ERROR_UNEXPECTED;

  cursor += sizeof(NTLM_SIGNATURE);

  // verify Type-2 marker
  if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_TYPE2_MARKER)) != 0)
    return NS_ERROR_UNEXPECTED;

  cursor += sizeof(NTLM_TYPE2_MARKER);

  // Read target name security buffer: ...
  // ... read target length.
  uint32_t targetLen = ReadUint16(cursor);
  // ... skip next 16-bit "allocated space" value.
  ReadUint16(cursor);
  // ... read offset from inBuf.
  uint32_t offset = ReadUint32(cursor);
  mozilla::CheckedInt<uint32_t> targetEnd = offset;
  targetEnd += targetLen;
  // Check the offset / length combo is in range of the input buffer, including
  // integer overflow checking.
  if (MOZ_LIKELY(targetEnd.isValid() && targetEnd.value() <= inLen)) {
    msg->targetLen = targetLen;
    msg->target = reinterpret_cast<const uint8_t*>(inBuf) + offset;
  } else {
    // Do not error out, for (conservative) backward compatibility.
    msg->targetLen = 0;
    msg->target = nullptr;
  }

  // read flags
  msg->flags = ReadUint32(cursor);

  // read challenge
  memcpy(msg->challenge, cursor, sizeof(msg->challenge));
  cursor += sizeof(msg->challenge);

  LOG(("NTLM type 2 message:\n"));
  LogBuf("target", reinterpret_cast<const uint8_t*> (msg->target), msg->targetLen);
  LogBuf("flags", reinterpret_cast<const uint8_t*> (&msg->flags), 4);
  LogFlags(msg->flags);
  LogBuf("challenge", msg->challenge, sizeof(msg->challenge));

  // Read (and skip) the reserved field
  ReadUint32(cursor);
  ReadUint32(cursor);
  // Read target name security buffer: ...
  // ... read target length.
  uint32_t targetInfoLen = ReadUint16(cursor);
  // ... skip next 16-bit "allocated space" value.
  ReadUint16(cursor);
  // ... read offset from inBuf.
  offset = ReadUint32(cursor);
  mozilla::CheckedInt<uint32_t> targetInfoEnd = offset;
  targetInfoEnd += targetInfoLen;
  // Check the offset / length combo is in range of the input buffer, including
  // integer overflow checking.
  if (MOZ_LIKELY(targetInfoEnd.isValid() && targetInfoEnd.value() <= inLen)) {
    msg->targetInfoLen = targetInfoLen;
    msg->targetInfo = reinterpret_cast<const uint8_t*>(inBuf) + offset;
  } else {
    NS_ERROR("failed to get NTLMv2 target info");
    return NS_ERROR_UNEXPECTED;
  }

  return NS_OK;
}
コード例 #15
0
	bool HTTPTracker::updateData(const QByteArray & data)
	{
//#define DEBUG_PRINT_RESPONSE
#ifdef DEBUG_PRINT_RESPONSE
		Out(SYS_TRK | LOG_DEBUG) << "Data : " << endl;
		Out(SYS_TRK | LOG_DEBUG) << QString(data) << endl;
#endif
		// search for dictionary, there might be random garbage infront of the data
		int i = 0;
		while (i < data.size())
		{
			if (data[i] == 'd')
				break;
			i++;
		}

		if (i == data.size())
		{
			failures++;
			failed(i18n("Invalid response from tracker"));
			return false;
		}

		BDecoder dec(data, false, i);
		BNode* n = 0;
		try
		{
			n = dec.decode();
		}
		catch (...)
		{
			failures++;
			failed(i18n("Invalid data from tracker"));
			return false;
		}

		if (!n || n->getType() != BNode::DICT)
		{
			failures++;
			failed(i18n("Invalid response from tracker"));
			return false;
		}

		BDictNode* dict = (BDictNode*)n;
		if (dict->getData("failure reason"))
		{
			BValueNode* vn = dict->getValue("failure reason");
			error = vn->data().toString();
			delete n;
			failures++;
			failed(error);
			return false;
		}

		if (dict->getData("warning message"))
		{
			BValueNode* vn = dict->getValue("warning message");
			warning = vn->data().toString();
		}
		else
			warning.clear();

		BValueNode* vn = dict->getValue("interval");

		// if no interval is specified, use 5 minutes
		if (vn)
			interval = vn->data().toInt();
		else
			interval = 5 * 60;

		vn = dict->getValue("incomplete");
		if (vn)
			leechers = vn->data().toInt();

		vn = dict->getValue("complete");
		if (vn)
			seeders = vn->data().toInt();

		BListNode* ln = dict->getList("peers");
		if (!ln)
		{
			// no list, it might however be a compact response
			vn = dict->getValue("peers");
			if (vn && vn->data().getType() == Value::STRING)
			{
				QByteArray arr = vn->data().toByteArray();
				for (int i = 0;i < arr.size();i += 6)
				{
					Uint8 buf[6];
					for (int j = 0;j < 6;j++)
						buf[j] = arr[i + j];

					Uint32 ip = ReadUint32(buf, 0);
					addPeer(net::Address(ip, ReadUint16(buf, 4)), false);
				}
			}
		}
		else
		{
			for (Uint32 i = 0;i < ln->getNumChildren();i++)
			{
				BDictNode* dict = dynamic_cast<BDictNode*>(ln->getChild(i));

				if (!dict)
					continue;

				BValueNode* ip_node = dict->getValue("ip");
				BValueNode* port_node = dict->getValue("port");

				if (!ip_node || !port_node)
					continue;

				net::Address addr(ip_node->data().toString(), port_node->data().toInt());
				addPeer(addr, false);
			}
		}

		// Check for IPv6 compact peers
		vn = dict->getValue("peers6");
		if (vn && vn->data().getType() == Value::STRING)
		{
			QByteArray arr = vn->data().toByteArray();
			for (int i = 0;i < arr.size();i += 18)
			{
				Q_IPV6ADDR ip;
				memcpy(ip.c, arr.data() + i, 16);
				quint16 port = ReadUint16((const Uint8*)arr.data() + i, 16);

				addPeer(net::Address(ip, port), false);
			}
		}

		delete n;
		return true;
	}
コード例 #16
0
ファイル: javaExecuter.cpp プロジェクト: flexme/xjoj
void JavaExecuter::run() {
    init();

    std::string workingDir = combineString(Config::getInstant()->getTmpUserPath(), DIR_SEPARTOR, runId);
   
    int port = 0, status;
    int server_sock = CreateServerSocket(&port);
    struct sockaddr_un un;
    socklen_t len = sizeof(un);

    if(server_sock < 0) {
        BLOG("JavaExecuter::run(): create server sock error", SYSCALL_ERROR);
        this->_result = SERVER_ERROR;
        return;
    }

    pid_t pid = fork();

    if(pid < 0) {
        BLOG("JavaExecuter::run() fork error", SYSCALL_ERROR);
        this->_result = SERVER_ERROR;
        return;
    }

    if(pid == 0) {
        close(server_sock);

        if(chdir(workingDir.c_str()) == -1) {
            LLOG("Fail to change working dir to " + workingDir, SYSCALL_ERROR);
            raise(SIGKILL);
            return;
        }
        
        std::string rootPath = Config::getInstant()->getRootPath();
        if(stdinFileName[0] != '/' && stdinFileName[0] != '.') {
            stdinFileName = rootPath + stdinFileName;
        }
        if(stdoutFileName[0] != '/' && stdoutFileName[0] != '/') {
            stdoutFileName = rootPath + stdoutFileName;
        }

        std::string minMem = combineString("-Xms", limitMemory / 2 + 200, 'k');
        std::string maxMem = combineString("-Xmx", limitMemory + 200, 'k');
        std::string javaLib = combineString("-Djava.library.path=", rootPath, "bin"); 
        std::string jarPath = combineString(rootPath, "bin/JavaSandbox.jar");
        std::string portStr = combineString(port);
        std::string limitTimeStr = combineString(limitTime);
        std::string limitMemoryStr = combineString(limitMemory);
        std::string limitOutputStr = combineString(limitOutput);
        std::string uidStr = combineString(Config::getInstant()->getJobUID());
        std::string gidStr = combineString(Config::getInstant()->getJobGID());

        for(int i = 0; i < 100; i++) close(i);

        execlp("java",
                minMem.c_str(),
                maxMem.c_str(),
                javaLib.c_str(),
                "-jar",
                jarPath.c_str(),
                portStr.c_str(),
                limitTimeStr.c_str(),
                limitMemoryStr.c_str(),
                limitOutputStr.c_str(),
                uidStr.c_str(),
                gidStr.c_str(),
                stdinFileName.c_str(),
                stdoutFileName.c_str(),
                NULL);

        LLOG("JavaExecuter()::run() Fail to run java", SYSCALL_ERROR);
        exit(-1);
    } else {
        //parent
        while(1) {
            //the accept function will be interuppted by the SIGCHLD signal
            int client_sock = accept(server_sock, (struct sockaddr*)&un, &len);

            if(client_sock < 0) {
                if(errno != EINTR) {
                    BLOG("JavaExecuter::run() fail to accept", SYSCALL_ERROR);
                    close(server_sock);
                    this->_result = SERVER_ERROR;
                    return;
                }else if(waitpid(pid, &status, WNOHANG) > 0) {
                    break;
                }
            } else {
                unsigned int _time, _memory;
                while(ReadUint32(client_sock, &_time) >= 0 &&
                    ReadUint32(client_sock, &_memory) >= 0) {
                    this->_runnedTime = _time;
                    this->_runnedMemory = _memory;
                    judgeThread->updateRunInfo(_time, _memory);
                }
                close(client_sock);
                while(waitpid(pid, &status, 0) < 0 && errno != ECHILD) {
                
                }
                break;
            }
        }
        close(server_sock);

        if(WIFSIGNALED(status)) {
            switch(WTERMSIG(status)) {
                case SIGXCPU:
                    this->_result = TIME_LIMIT_EXCEEDED;
                    break;
                default:
                    DLOG(ERROR) << "Java process was terminated by signal " << WTERMSIG(status);
                    this->_result = RUNTIME_ERROR;
            }
        } else {
            this->_result = WEXITSTATUS(status);
            if(this->_result == 1) {
                this->_result = SERVER_ERROR;
            }else{
                if(this->_result)
                    this->_result += 1000;
            }

            if(this->_result == 0) {
                this->_result = TraceProcess::NORMAL;
                if(this->_runnedMemory > limitMemory) {
                    this->_result = MEMORY_LIMIT_EXCEEDED;
                }

                if(this->_runnedTime > limitTime) {
                    this->_result = TIME_LIMIT_EXCEEDED;
                }
            }
        }
    }
}