Embedding data into JPEG
2014-05-08 22:36
316 查看
/**
* segmentset.cpp
*
* Created on Apr 17, 2014
* Author: jiejing shan
*/
#include "segmentset.h"
#include "Log4Android.h"
#include "jpeg.h"
#define TAG "segmentset"
using namespace std;
bool SegmentSet::format(const char* data, const int dataLen, JPEG_MARKER marker, string segmentName)
{
if (data == NULL || dataLen == 0) {
return false;
}
if (!this->mmSet.empty()) {
this->mmSet.clear();
this->miSegmentNum = 0;
}
if (this->mpcBuff != NULL) {
delete [] this->mpcBuff;
this->mpcBuff = NULL;
}
int maxDataLen = Segment::getSegmentDataMaxLength(segmentName.size());
LOGE(TAG, "segment name length = %d, maxDataLen = %d\n", segmentName.size(), maxDataLen);
// chunks number
int totalNumber = (dataLen + (maxDataLen - 1)) / maxDataLen;
LOGE(TAG, "total number is %d\n", totalNumber);
int lastSegmentDataLen = dataLen % maxDataLen;
int buffSize = Segment::MAX_BYTES_SEGMENT * (totalNumber - 1)
+ lastSegmentDataLen
+ Segment::getSegmentHeadLength(segmentName.size());
LOGE(TAG, "buff size is %d\n", buffSize);
this->mpcBuff = new char[buffSize];
if (this->mpcBuff == NULL) {
return false;
}
this->miBuffLen = buffSize;
this->mJpegMarker = marker;
this->msSegmentName = segmentName;
int iFormatDataLen = maxDataLen;
const char* pcFormatData = data;
bool ret = true;
int i = 0;
for(i = 0; i < totalNumber; i ++) {
if (i == (totalNumber - 1)) {
iFormatDataLen = lastSegmentDataLen;
}
pcFormatData = data + i * maxDataLen;
Segment *pseg = new Segment(marker, segmentName);
if (pseg == NULL) {
break;
}
ret = pseg->formatSegment(this->mpcBuff + (i * Segment::MAX_BYTES_SEGMENT), pcFormatData, iFormatDataLen, i + 1, totalNumber);
if (!ret) {
delete pseg;
break;
}
this->mmSet.push_back(*pseg);
}
if ((i != totalNumber) || !ret) {
this->mmSet.clear();
delete [] this->mpcBuff;
this->mpcBuff = NULL;
return false;
}
this->miSegmentNum = totalNumber;
return true;
}
int SegmentSet::getSegmentByIndex(const int index, Segment& ret)
{
if ((index < 0) || (index >= this->miSegmentNum)) {
return -1;
}
list<Segment>::iterator it;
int i = 0;
for (it = this->mmSet.begin(); it != this->mmSet.end(); it ++) {
if (i == index) {
ret = *it;
return 0;
}
}
return -1;
}
bool SegmentSet::addSegmentSet(const SegmentSet other)
{
//I don't know why this method can't be called.
//this->mmSet.merge(other.mmSet);
this->miSegmentNum += other.miSegmentNum;
}
/**
* @brief checkSegmentHead
* parse the file stream, and get the segment head, if the head's every
* fields is valid, return them by the out put parameters, or , if the
* return isn't 0, it means the head is invalid.
* after checked, the file stream's read position must be as the same as before.
*
* @param is
* @param tag
* @param len
* @param segmentName
* @param chunkNum
* @param maxChunkNum
*
* @return 0, successful
* -1, tag is not 0xFFE3.
* -2, the head length, the chunk number or the max chunk number is invalid.
* -3, the segment name of file isn't the same segment name;
*/
int SegmentSet::checkSegmentHead(ifstream& is, unsigned short& tag, int& len, string& segmentName, int& chunkNum, int& maxChunkNum) {
char buff[2] = "\0";
unsigned short tmpTag = 0;
int tmpLen = 0;
char segName[64] = "\0";
int segNameLen = 0;
int tmpChunkNum = 0;
int tmpMaxChunkNum = 0;
is.read(buff, 2);
tmpTag = ((unsigned short)buff[0] << 8) | (unsigned short)buff[1];
if (tmpTag != Jpeg::DEPTH_APP_SEG) {
is.seekg(-2, ios::cur);
return -1;
}
is.read(buff, 2);
//tmpLen = ((unsigned short)buff[0] << 8) | (unsigned short)buff[1];
tmpLen = ((unsigned char)buff[0] << 8) | (unsigned char)buff[1];
LOGE(TAG, "checkSegmentHead: tmpLen %d", tmpLen);
if (tmpLen > Segment::MAX_BYTES_SEGMENT ||
tmpLen < 0) {
is.seekg(-4, ios::cur);
return -2;
}
do {
is.read(buff, 1);
segName[segNameLen ++] = buff[0];
} while(buff[0] != '\0');
LOGE(TAG, "segment name len is %d, head len is %d\n", segNameLen, Segment::getSegmentHeadLength(segNameLen - 1));
if (segmentName.size() != 0 &&
(0 != strcmp(segmentName.c_str(), segName))) {
is.seekg((0 - segNameLen - 4), ios::cur);
return -3;
}
is.read(buff, 2);
tmpChunkNum = (unsigned char)buff[0];
tmpMaxChunkNum = (unsigned char)buff[1];
if ((tmpChunkNum < 1) ||
(tmpMaxChunkNum < 1) ||
(tmpChunkNum > tmpMaxChunkNum))
{
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen - 1))), ios::cur);
return -2;
}
if (tmpMaxChunkNum > 1) {
if (tmpChunkNum != tmpMaxChunkNum &&
tmpLen != Segment::MAX_BYTES_SEGMENT - 2) {
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen -1))), ios::cur);
return -2;
}
}
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen -1))), ios::cur);
tag = tmpTag;
len = tmpLen;
segmentName = segName;
chunkNum = tmpChunkNum;
maxChunkNum = tmpMaxChunkNum;
return 0;
}
int SegmentSet::parse(ifstream& is)
{
if (is.fail()) {
LOGE(TAG, "file stream is fail!");
return -1;
}
unsigned short tag = 0;
int len = 0;
string segmentName;
int chunkNum = 0;
int maxChunkNum = 0;
int maxSegSetLen = 0;
int ret = 0;
if (this->mpcBuff != NULL) {
this->release();
}
do {
ret = checkSegmentHead(is, tag, len, segmentName, chunkNum, maxChunkNum);
if (ret < 0) {
LOGE(TAG, "check segment head error");
break;
}
LOGI(TAG, "read a segment head ret = %d, tag is %x, len is %x, segment name is %s, chunk num is %d, max chunk number is %d\n",
ret, tag, len, segmentName.c_str(), chunkNum, maxChunkNum);
is.seekg(len + 2, ios::cur);
maxSegSetLen += len + 2;
if (chunkNum == maxChunkNum)
break;
} while(1);
if (ret < 0) {
return -1;
}
this->mpcBuff = new char[maxSegSetLen];
if (this->mpcBuff == NULL) {
LOGE(TAG, "not enough memory");
return -1;
}
is.seekg((0 - maxSegSetLen), ios::cur);
is.read(this->mpcBuff, maxSegSetLen);
this->miBuffLen = maxSegSetLen;
this->mJpegMarker = (JPEG_MARKER)tag;
this->msSegmentName = segmentName;
for (int i = 1; i <= maxChunkNum; i ++) {
Segment seg((JPEG_MARKER)tag, segmentName);
seg.parse(this->mpcBuff + ((i - 1) * Segment::MAX_BYTES_SEGMENT));
this->mmSet.push_back(seg);
}
this->miSegmentNum = maxChunkNum;
LOGE(TAG , "leave segment set parse");
return ret;
}
int SegmentSet::getDataLength() const
{
int allDataLen = 0;
LOGE(TAG, "segment size is %d", this->mmSet.size());
for(list<Segment>::const_iterator it = this->mmSet.begin(); it != this->mmSet.end(); it++)
{
LOGE(TAG, "segment data len is %ud\n", it->getSegmentDataLength());
allDataLen += it->getSegmentDataLength();
}
return allDataLen;
}
/*
* user will ensure the pcData buff have enough memory.
*/
int SegmentSet::getData(const char* pcData) const
{
if (pcData == NULL) {
return -1;
}
const char* pcTmp = pcData;
for(list<Segment>::const_iterator it = this->mmSet.begin(); it != this->mmSet.end(); it++)
{
memcpy((void*)pcTmp, it->getSegmentData(), it->getSegmentDataLength());
pcTmp += it->getSegmentDataLength();
}
return 0;
}
/**
* segment.cpp
*
* Created on Apr 17, 2014
* Author : jiejing shan
*/
#include "segment.h"
#include <string>
#include "../library/Log4Android.h"
using namespace std;
#define TAG "segment"
const int Segment::MAX_BYTES_SEGMENT = 65535;
int Segment::getSegmentDataMaxLength(const int segNameLen)
{
//2 bytes APP MAKER, 2 bytes TAG LENGTH, 1 byte chunk number, 1 byte max chunk number, segment name length and '\0'
int iSegmentHeadLen = segNameLen + 1 + 6;
return MAX_BYTES_SEGMENT - iSegmentHeadLen;
}
int Segment::getSegmentDataLength() const
{
return this->miDataLen;
}
int Segment::getSegmentLength()
{
//data length, segment name length and '\0', 2 bytes TAG length, 1 bytes chunk number, 1 bytes max chunk number
return this->miDataLen + this->msSegmentName.size() + 1 + 4;
}
char* Segment::getSegmentData() const
{
return this->mpcStart + getSegmentHeadLength(this->msSegmentName.size());
}
string Segment::getSegmentName()
{
return this->msSegmentName;
}
JPEG_MARKER Segment::getSegmentMarker()
{
return this->mMarker;
}
int Segment::getSegmentHeadLength(const int segNameLen)
{
return segNameLen + 1 + 6;
}
/*
* formatSegment
* according to the data, chunk number and max chunk number, format the segment buffer
* the pcBuff must be had enough memory to contain segment head and data.
*/
bool Segment::formatSegment(char* pcBuff, const char* data, const int dataLen, const int chunkNum, const int maxChunkNum)
{
if (pcBuff == NULL) {
return false;
}
memset(pcBuff, 0, getSegmentHeadLength(this->msSegmentName.size()) + dataLen);
this->mpcStart = pcBuff;
this->miDataLen = dataLen;
this->miChunkNum = chunkNum;
this->miMaxChunkNum = maxChunkNum;
char* pTmp = this->mpcStart;
int len = getSegmentLength();
*pTmp = (char)((((int)this->mMarker) & 0xFF00) >> 8);
pTmp ++;
*pTmp = (char)(((int)this->mMarker) & 0x00FF);
pTmp ++;
*pTmp = (char) ((len & 0xFF00) >> 8);
pTmp ++;
*pTmp = (char) (len & 0x00FF);
pTmp ++;
memcpy(pTmp, this->msSegmentName.c_str(), this->msSegmentName.size());
pTmp += this->msSegmentName.size() + 1;
*pTmp = (char) (chunkNum & 0x00FF);
pTmp ++;
*pTmp = (char) (maxChunkNum & 0xFF);
pTmp ++;
memcpy(pTmp, data, dataLen);
return true;
}
/*
* init
* according a segment buffer, construct a segment class
* uncompleted.
*/
Segment Segment::init(char* buff)
{
char name[64] = "\0";
char* pTmp = buff;
int marker = (pTmp[0] << 8) + pTmp[1];
pTmp += 2;
int segLen = (pTmp[0] << 8) + pTmp[1];
pTmp += 2;
strcpy(name, pTmp);
int nameLen = strlen(name);
pTmp += nameLen + 1;
int chunkNum = pTmp[0];
pTmp ++;
int maxChunkNum = pTmp[0];
pTmp ++;
//Segment *pSegment = new Segment((JPG_APP_MARKER)marker, name);
//pSegment->mpcBuffer
}
int Segment::parse(char* buff)
{
const char* pcTmp = buff;
this->mpcStart = buff;
pcTmp += 2;
int len = ((unsigned char)pcTmp[0] << 8) | (unsigned char)pcTmp[1];
//int len = ((unsigned short)pcTmp[0] << 8) | (unsigned short)pcTmp[1];
LOGE(TAG, "parse len is %d\n", len);
pcTmp += 2;
this->miDataLen = len - this->msSegmentName.size() - 1 - 4;
LOGE(TAG, "data len is %d\n", this->miDataLen);
pcTmp += this->msSegmentName.size() + 1;
this->miChunkNum = (unsigned char)pcTmp[0];
this->miMaxChunkNum = (unsigned char)pcTmp[1];
}
* segmentset.cpp
*
* Created on Apr 17, 2014
* Author: jiejing shan
*/
#include "segmentset.h"
#include "Log4Android.h"
#include "jpeg.h"
#define TAG "segmentset"
using namespace std;
bool SegmentSet::format(const char* data, const int dataLen, JPEG_MARKER marker, string segmentName)
{
if (data == NULL || dataLen == 0) {
return false;
}
if (!this->mmSet.empty()) {
this->mmSet.clear();
this->miSegmentNum = 0;
}
if (this->mpcBuff != NULL) {
delete [] this->mpcBuff;
this->mpcBuff = NULL;
}
int maxDataLen = Segment::getSegmentDataMaxLength(segmentName.size());
LOGE(TAG, "segment name length = %d, maxDataLen = %d\n", segmentName.size(), maxDataLen);
// chunks number
int totalNumber = (dataLen + (maxDataLen - 1)) / maxDataLen;
LOGE(TAG, "total number is %d\n", totalNumber);
int lastSegmentDataLen = dataLen % maxDataLen;
int buffSize = Segment::MAX_BYTES_SEGMENT * (totalNumber - 1)
+ lastSegmentDataLen
+ Segment::getSegmentHeadLength(segmentName.size());
LOGE(TAG, "buff size is %d\n", buffSize);
this->mpcBuff = new char[buffSize];
if (this->mpcBuff == NULL) {
return false;
}
this->miBuffLen = buffSize;
this->mJpegMarker = marker;
this->msSegmentName = segmentName;
int iFormatDataLen = maxDataLen;
const char* pcFormatData = data;
bool ret = true;
int i = 0;
for(i = 0; i < totalNumber; i ++) {
if (i == (totalNumber - 1)) {
iFormatDataLen = lastSegmentDataLen;
}
pcFormatData = data + i * maxDataLen;
Segment *pseg = new Segment(marker, segmentName);
if (pseg == NULL) {
break;
}
ret = pseg->formatSegment(this->mpcBuff + (i * Segment::MAX_BYTES_SEGMENT), pcFormatData, iFormatDataLen, i + 1, totalNumber);
if (!ret) {
delete pseg;
break;
}
this->mmSet.push_back(*pseg);
}
if ((i != totalNumber) || !ret) {
this->mmSet.clear();
delete [] this->mpcBuff;
this->mpcBuff = NULL;
return false;
}
this->miSegmentNum = totalNumber;
return true;
}
int SegmentSet::getSegmentByIndex(const int index, Segment& ret)
{
if ((index < 0) || (index >= this->miSegmentNum)) {
return -1;
}
list<Segment>::iterator it;
int i = 0;
for (it = this->mmSet.begin(); it != this->mmSet.end(); it ++) {
if (i == index) {
ret = *it;
return 0;
}
}
return -1;
}
bool SegmentSet::addSegmentSet(const SegmentSet other)
{
//I don't know why this method can't be called.
//this->mmSet.merge(other.mmSet);
this->miSegmentNum += other.miSegmentNum;
}
/**
* @brief checkSegmentHead
* parse the file stream, and get the segment head, if the head's every
* fields is valid, return them by the out put parameters, or , if the
* return isn't 0, it means the head is invalid.
* after checked, the file stream's read position must be as the same as before.
*
* @param is
* @param tag
* @param len
* @param segmentName
* @param chunkNum
* @param maxChunkNum
*
* @return 0, successful
* -1, tag is not 0xFFE3.
* -2, the head length, the chunk number or the max chunk number is invalid.
* -3, the segment name of file isn't the same segment name;
*/
int SegmentSet::checkSegmentHead(ifstream& is, unsigned short& tag, int& len, string& segmentName, int& chunkNum, int& maxChunkNum) {
char buff[2] = "\0";
unsigned short tmpTag = 0;
int tmpLen = 0;
char segName[64] = "\0";
int segNameLen = 0;
int tmpChunkNum = 0;
int tmpMaxChunkNum = 0;
is.read(buff, 2);
tmpTag = ((unsigned short)buff[0] << 8) | (unsigned short)buff[1];
if (tmpTag != Jpeg::DEPTH_APP_SEG) {
is.seekg(-2, ios::cur);
return -1;
}
is.read(buff, 2);
//tmpLen = ((unsigned short)buff[0] << 8) | (unsigned short)buff[1];
tmpLen = ((unsigned char)buff[0] << 8) | (unsigned char)buff[1];
LOGE(TAG, "checkSegmentHead: tmpLen %d", tmpLen);
if (tmpLen > Segment::MAX_BYTES_SEGMENT ||
tmpLen < 0) {
is.seekg(-4, ios::cur);
return -2;
}
do {
is.read(buff, 1);
segName[segNameLen ++] = buff[0];
} while(buff[0] != '\0');
LOGE(TAG, "segment name len is %d, head len is %d\n", segNameLen, Segment::getSegmentHeadLength(segNameLen - 1));
if (segmentName.size() != 0 &&
(0 != strcmp(segmentName.c_str(), segName))) {
is.seekg((0 - segNameLen - 4), ios::cur);
return -3;
}
is.read(buff, 2);
tmpChunkNum = (unsigned char)buff[0];
tmpMaxChunkNum = (unsigned char)buff[1];
if ((tmpChunkNum < 1) ||
(tmpMaxChunkNum < 1) ||
(tmpChunkNum > tmpMaxChunkNum))
{
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen - 1))), ios::cur);
return -2;
}
if (tmpMaxChunkNum > 1) {
if (tmpChunkNum != tmpMaxChunkNum &&
tmpLen != Segment::MAX_BYTES_SEGMENT - 2) {
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen -1))), ios::cur);
return -2;
}
}
is.seekg((0 - (Segment::getSegmentHeadLength(segNameLen -1))), ios::cur);
tag = tmpTag;
len = tmpLen;
segmentName = segName;
chunkNum = tmpChunkNum;
maxChunkNum = tmpMaxChunkNum;
return 0;
}
int SegmentSet::parse(ifstream& is)
{
if (is.fail()) {
LOGE(TAG, "file stream is fail!");
return -1;
}
unsigned short tag = 0;
int len = 0;
string segmentName;
int chunkNum = 0;
int maxChunkNum = 0;
int maxSegSetLen = 0;
int ret = 0;
if (this->mpcBuff != NULL) {
this->release();
}
do {
ret = checkSegmentHead(is, tag, len, segmentName, chunkNum, maxChunkNum);
if (ret < 0) {
LOGE(TAG, "check segment head error");
break;
}
LOGI(TAG, "read a segment head ret = %d, tag is %x, len is %x, segment name is %s, chunk num is %d, max chunk number is %d\n",
ret, tag, len, segmentName.c_str(), chunkNum, maxChunkNum);
is.seekg(len + 2, ios::cur);
maxSegSetLen += len + 2;
if (chunkNum == maxChunkNum)
break;
} while(1);
if (ret < 0) {
return -1;
}
this->mpcBuff = new char[maxSegSetLen];
if (this->mpcBuff == NULL) {
LOGE(TAG, "not enough memory");
return -1;
}
is.seekg((0 - maxSegSetLen), ios::cur);
is.read(this->mpcBuff, maxSegSetLen);
this->miBuffLen = maxSegSetLen;
this->mJpegMarker = (JPEG_MARKER)tag;
this->msSegmentName = segmentName;
for (int i = 1; i <= maxChunkNum; i ++) {
Segment seg((JPEG_MARKER)tag, segmentName);
seg.parse(this->mpcBuff + ((i - 1) * Segment::MAX_BYTES_SEGMENT));
this->mmSet.push_back(seg);
}
this->miSegmentNum = maxChunkNum;
LOGE(TAG , "leave segment set parse");
return ret;
}
int SegmentSet::getDataLength() const
{
int allDataLen = 0;
LOGE(TAG, "segment size is %d", this->mmSet.size());
for(list<Segment>::const_iterator it = this->mmSet.begin(); it != this->mmSet.end(); it++)
{
LOGE(TAG, "segment data len is %ud\n", it->getSegmentDataLength());
allDataLen += it->getSegmentDataLength();
}
return allDataLen;
}
/*
* user will ensure the pcData buff have enough memory.
*/
int SegmentSet::getData(const char* pcData) const
{
if (pcData == NULL) {
return -1;
}
const char* pcTmp = pcData;
for(list<Segment>::const_iterator it = this->mmSet.begin(); it != this->mmSet.end(); it++)
{
memcpy((void*)pcTmp, it->getSegmentData(), it->getSegmentDataLength());
pcTmp += it->getSegmentDataLength();
}
return 0;
}
/**
* segment.cpp
*
* Created on Apr 17, 2014
* Author : jiejing shan
*/
#include "segment.h"
#include <string>
#include "../library/Log4Android.h"
using namespace std;
#define TAG "segment"
const int Segment::MAX_BYTES_SEGMENT = 65535;
int Segment::getSegmentDataMaxLength(const int segNameLen)
{
//2 bytes APP MAKER, 2 bytes TAG LENGTH, 1 byte chunk number, 1 byte max chunk number, segment name length and '\0'
int iSegmentHeadLen = segNameLen + 1 + 6;
return MAX_BYTES_SEGMENT - iSegmentHeadLen;
}
int Segment::getSegmentDataLength() const
{
return this->miDataLen;
}
int Segment::getSegmentLength()
{
//data length, segment name length and '\0', 2 bytes TAG length, 1 bytes chunk number, 1 bytes max chunk number
return this->miDataLen + this->msSegmentName.size() + 1 + 4;
}
char* Segment::getSegmentData() const
{
return this->mpcStart + getSegmentHeadLength(this->msSegmentName.size());
}
string Segment::getSegmentName()
{
return this->msSegmentName;
}
JPEG_MARKER Segment::getSegmentMarker()
{
return this->mMarker;
}
int Segment::getSegmentHeadLength(const int segNameLen)
{
return segNameLen + 1 + 6;
}
/*
* formatSegment
* according to the data, chunk number and max chunk number, format the segment buffer
* the pcBuff must be had enough memory to contain segment head and data.
*/
bool Segment::formatSegment(char* pcBuff, const char* data, const int dataLen, const int chunkNum, const int maxChunkNum)
{
if (pcBuff == NULL) {
return false;
}
memset(pcBuff, 0, getSegmentHeadLength(this->msSegmentName.size()) + dataLen);
this->mpcStart = pcBuff;
this->miDataLen = dataLen;
this->miChunkNum = chunkNum;
this->miMaxChunkNum = maxChunkNum;
char* pTmp = this->mpcStart;
int len = getSegmentLength();
*pTmp = (char)((((int)this->mMarker) & 0xFF00) >> 8);
pTmp ++;
*pTmp = (char)(((int)this->mMarker) & 0x00FF);
pTmp ++;
*pTmp = (char) ((len & 0xFF00) >> 8);
pTmp ++;
*pTmp = (char) (len & 0x00FF);
pTmp ++;
memcpy(pTmp, this->msSegmentName.c_str(), this->msSegmentName.size());
pTmp += this->msSegmentName.size() + 1;
*pTmp = (char) (chunkNum & 0x00FF);
pTmp ++;
*pTmp = (char) (maxChunkNum & 0xFF);
pTmp ++;
memcpy(pTmp, data, dataLen);
return true;
}
/*
* init
* according a segment buffer, construct a segment class
* uncompleted.
*/
Segment Segment::init(char* buff)
{
char name[64] = "\0";
char* pTmp = buff;
int marker = (pTmp[0] << 8) + pTmp[1];
pTmp += 2;
int segLen = (pTmp[0] << 8) + pTmp[1];
pTmp += 2;
strcpy(name, pTmp);
int nameLen = strlen(name);
pTmp += nameLen + 1;
int chunkNum = pTmp[0];
pTmp ++;
int maxChunkNum = pTmp[0];
pTmp ++;
//Segment *pSegment = new Segment((JPG_APP_MARKER)marker, name);
//pSegment->mpcBuffer
}
int Segment::parse(char* buff)
{
const char* pcTmp = buff;
this->mpcStart = buff;
pcTmp += 2;
int len = ((unsigned char)pcTmp[0] << 8) | (unsigned char)pcTmp[1];
//int len = ((unsigned short)pcTmp[0] << 8) | (unsigned short)pcTmp[1];
LOGE(TAG, "parse len is %d\n", len);
pcTmp += 2;
this->miDataLen = len - this->msSegmentName.size() - 1 - 4;
LOGE(TAG, "data len is %d\n", this->miDataLen);
pcTmp += this->msSegmentName.size() + 1;
this->miChunkNum = (unsigned char)pcTmp[0];
this->miMaxChunkNum = (unsigned char)pcTmp[1];
}
相关文章推荐
- 继承 内存分布
- uva10129
- Asp.Net MVC 分页、检索、排序整体实现
- C#向RichTextBox写入数据并始终显示在最下方
- cuda编程:不要在一个cpp文件中声明__device__和__global__函数
- 编程方式读取硬盘信息 - MBR以及各个分区信息
- 移动开发之iOS基础开发(四)更加丰富的用户界面
- 如何扩展 Visual Studio 编辑器
- Careercup - Google面试题 - 6331648220069888
- 常用Jar包说明
- 理解核心
- ios 年龄的时间换算
- 顺序栈
- linux命令之service和chkconfig
- SSIS从理论到实战,再到应用(7)----常用的数据类型转换操作
- SSIS从理论到实战,再到应用(6)----SSIS的自带日志功能
- 理解核心
- 使用ndk-build编译 android调用的so库
- linux-2.6.26下开发marvell 88w8686 wifi驱动
- SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环