Example #1
0
static void
ReadSecBuf(SecBuf *s, const PRUint8 *&buf)
{
    s->length = ReadUint16(buf);
    s->capacity = ReadUint16(buf);
    s->offset = ReadUint32(buf);
}
Example #2
0
static void
ReadType2MsgBody(const PRUint8 *inBuf, PRUint32 start)
{
    PRUint16 targetLen, offset;
    PRUint32 flags;
    const PRUint8 *target;
    const PRUint8 *cursor = inBuf + start;

    // read target name security buffer
    targetLen = ReadUint16(cursor);
    ReadUint16(cursor); // discard next 16-bit value
    offset = ReadUint32(cursor); // get offset from inBuf
    target = inBuf + offset;

    PrintBuf("target", target, targetLen);

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

    // read challenge
    PrintBuf("challenge", cursor, 8);
    cursor += 8;

    PrintBuf("context", cursor, 8);
    cursor += 8;

    SecBuf secbuf;
    ReadSecBuf(&secbuf, cursor);
    PrintBuf("target information", inBuf + secbuf.offset, secbuf.length);
}
      /// parses event data
      void Parse(unsigned int uiNumParam)
      {
         // note that buffer pointer is at pos 4 already
         prUInt16 uiContainerType = ReadUint16();
         m_uiEventCode = ReadUint16();
         prUInt32 uiTransactionId = ReadUint32();

         UNUSED(uiContainerType);
         UNUSED(uiTransactionId);

         // read all parameters
         for (unsigned int ui = 0; ui < uiNumParam; ui++)
            m_vecParams.push_back(ReadUint32());
      }
Example #4
0
int32 UnpackSavedataAck(EdpPacket* pkg, char** json_ack)
{
    uint32 remainlen;
    uint8 flag;
    uint16 json_len;

    if (ReadRemainlen(pkg, &remainlen))
    {
        return ERR_UNPACK_SAVEDATA_ACK;
    }


    if (ReadByte(pkg, &flag))
    {
        return ERR_UNPACK_SAVEDATA_ACK;
    }


    if (ReadUint16(pkg, &json_len))
    {
        return ERR_UNPACK_SAVEDATA_ACK;
    }

    if (ReadBytes(pkg, (uint8**)(json_ack), json_len))
    {
        return ERR_UNPACK_SAVEDATA_ACK;
    }

    return 0;
}
Example #5
0
int32 UnpackEncryptResp(EdpPacket* pkg){
    uint32 remainlen = 0;
    uint16 key_len = 0;

    unsigned rsa_size = 0;
    unsigned slice_size = 0;
    
    unsigned char key[BUFFER_SIZE] = {0};
    unsigned decrypt_len = 0;
    int len = 0;
    unsigned char* from = 0;
    unsigned char* to = 0;
    uint32 i = 0;

    if (ReadRemainlen(pkg, &remainlen))
	return ERR_UNPACK_ENCRYPT_RESP;

    if (ReadUint16(pkg, &key_len))
	return ERR_UNPACK_ENCRYPT_RESP;
    
    if (remainlen != key_len + 2)
	return ERR_UNPACK_ENCRYPT_RESP;

    rsa_size = RSA_size(g_rsa);
    slice_size = rsa_size - RSA_PADDING_LEN;
    
    from = pkg->_data + pkg->_read_pos;
    to = key;
    
    for (i=0; i<key_len; i+=rsa_size){
	len = RSA_private_decrypt(rsa_size, from+i, to, 
				  g_rsa, RSA_PKCS1_PADDING);
	decrypt_len += len;
	if (decrypt_len > BUFFER_SIZE){
	    return ERR_UNPACK_ENCRYPT_RESP;
	}

	to += len;
    }

    switch (g_encrypt_alg_type){
    case kTypeAes:
	if(AES_set_encrypt_key(key, AES_KEY_LEN, &g_aes_encrypt_key) < 0) {
	    return ERR_UNPACK_ENCRYPT_RESP;
	}

	if(AES_set_decrypt_key(key, AES_KEY_LEN, &g_aes_decrypt_key) < 0) {
	    return ERR_UNPACK_ENCRYPT_RESP;
	}
	break;

    default:
	return ERR_UNPACK_ENCRYPT_RESP;
	break;
    }

    return 0;
}
Example #6
0
otError SpinelDecoder::ReadInt16(int16_t &aInt16)
{
    otError  error = OT_ERROR_NONE;
    uint16_t u16;

    SuccessOrExit(error = ReadUint16(u16));
    aInt16 = static_cast<int16_t>(u16);

exit:
    return error;
}
Example #7
0
otError SpinelDecoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen)
{
    otError  error = OT_ERROR_NONE;
    uint16_t len;

    SuccessOrExit(error = ReadUint16(len));
    SuccessOrExit(error = ReadItem(&aData, len));
    aDataLen = len;

exit:
    return error;
}
Example #8
0
int32 ReadStr(EdpPacket* pkg, char** val)
{
    uint16 len;
    /* read str len */
    int rc = ReadUint16(pkg, &len);
    if (rc)
        return rc;
    if (pkg->_read_pos+len > pkg->_write_pos)
        return -1;
    /* copy str val */
    *val = (char*)hx_malloc(sizeof(char) * (len + 1));
    mymemset(*val, 0, len+1);
    strncpy(*val, (const char *)(pkg->_data + pkg->_read_pos), len);
    pkg->_read_pos += len;
    return 0;
}
int32_t ReadStr(EdpPacket* pkg, int8_t** val)
{
    uint16_t len = 0;
    int32_t rc = 0;
    /* read str len */
    rc = ReadUint16(pkg, &len);
    if (rc)
        return rc;
    if (pkg->_read_pos + len > pkg->_write_pos)
        return -1;
    /* copy str val */
    *val = malloc(sizeof(char) * (len + 1));
    memset(*val, 0, len + 1);
    strncpy((char *)*val, (const char *)(pkg->_data + pkg->_read_pos), len);
    pkg->_read_pos += len;
    return 0;
}
Example #10
0
otError SpinelDecoder::OpenStruct(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t structLen;

    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);

    SuccessOrExit(error = ReadUint16(structLen));
    VerifyOrExit(structLen <= mEnd - mIndex, error = OT_ERROR_PARSE);

    mPrevEnd[mNumOpenStructs] = mEnd;
    mEnd                      = (mIndex + structLen);
    mNumOpenStructs++;

exit:
    return error;
}
int32_t UnpackSavedataAck(EdpPacket* pkg, int8_t** json_ack)
{
    uint32_t remainlen = 0;
    uint8_t flag = 0;
    uint16_t json_len = 0;

    if (ReadRemainlen(pkg, &remainlen))
        return ERR_UNPACK_SAVEDATA_ACK;

    if (ReadByte(pkg, &flag))
        return ERR_UNPACK_SAVEDATA_ACK;

    if (ReadUint16(pkg, &json_len))
        return ERR_UNPACK_SAVEDATA_ACK;

    if (ReadBytes(pkg, (uint8_t**)(json_ack), json_len))
        return ERR_UNPACK_SAVEDATA_ACK;

    return 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;
}
Example #13
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;
	}
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;
}
Example #15
0
/**
 *
 * 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;
}
Example #16
0
/**
	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;
}
Example #17
0
/**
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);

}
Example #18
0
//
// @param pInput 输入流
//============================================================
TResult FUiControl::OnUnserialize(IDataInput* pInput){
   MO_CHECK(pInput, return ENull);
   // 读取属性
   _flags = pInput->ReadInt32();
   _name.Unserialize(pInput);
   _label.UnserializeAutomatic(pInput);
   // 读取位置
   _optionEnable = TestFlag(EControlFlag_Enable);
   _optionVisible = TestFlag(EControlFlag_Visible);
   _dockCd = (EControlDock)pInput->ReadUint8();
   _location.x = pInput->ReadInt16();
   _location.y = pInput->ReadInt16();
   _size.width = pInput->ReadUint16();
   _size.height = pInput->ReadUint16();
   // 读取边距
   if(TestFlag(EControlFlag_Margin)){
      _margin.Unserialize8(pInput);
   }
   if(TestFlag(EControlFlag_Padding)){
      _padding.Unserialize8(pInput);
   }
   // 读取边框
   if(TestFlag(EControlFlag_BorderOuter)){
      _borderOuter.Unserialize(pInput);
   }
   if(TestFlag(EControlFlag_BorderInner)){
      _borderInner.Unserialize(pInput);
   }         
Example #19
0
void
nsSOCKSSocketInfo::ReadNetPort(PRNetAddr *addr)
{
    addr->inet.port = ReadUint16();
}
Example #20
0
/**
	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;
}