I am using podofo 0.9.3 library for digital signing pdf document using PdfSigIncMemDocument class. I am able to digitally sign pdf without any issue, but the output pdf file size is very big.
Here is my code
PdfSigIncMemDocument doc("e:\\sample.pdf");
char *buffer = NULL;
buffer = (char *)malloc(809600);
PdfOutputDevice output(buffer, 809600);
PdfSignOutputDevice signOutput(&output);
signOutput.SetSignatureSize(2048);
printf( "Page count:%d\n", doc.GetPageCount());
PdfSigIncSignatureField *sign = doc.GetSignatureField();
sign->SetSignatureDate(PdfDate());
sign->SetSignatureReason(L"I dont agree");
sign->SetSignatureImage("e:\\sign.jpg", 0, 100, 200, 100, 100);
sign->SetSignatureText(L"Hello World", 0, 100, 200, 100, 100, 12);
doc.Initialize();
doc.CreateVisualSign();
doc.Write(&signOutput);
printf( "Has Signature:%d\n", signOutput.HasSignaturePosition());
char buff[809600] = {0};
size_t len;
BYTE *Signature = NULL;
DWORD cbSignature = 0;
signOutput.AdjustByteRange();
signOutput.Seek(0);
len = signOutput.ReadForSignature(buff, 809600);
printf("total tbs size: %d\n", len);
SignMessage( (BYTE *)buff, len, &Signature, &cbSignature);//Digital signing using MSCAPI
printf("signature size: %d\n", cbSignature);
const PoDoFo::PdfData *sig = new PoDoFo::PdfData((char *)Signature, cbSignature);
signOutput.SetSignature(*sig);
signOutput.Flush();
FILE *fp = NULL;
fp = fopen( "e:\sign.pdf", "wb" );
fwrite( buffer, signOutput.GetLength(), 1, fp );
fclose(fp);
Size of sample.pdf is 31KB whereas the output sign.pdf size is 506KB.
can some one help with this issue ?
Related
I have a device connected to serial port and waiting for a file to be transmited using xmodem protocol.
I have tried constructing a message using in xmodem format and sending it, however I'm not getting the expected ACK for the transfer.
Bellow are the relevant bits of code:
Format of XMODEM message:
struct xmodem_packet
{
uint8_t start;
uint8_t block;
uint8_t block_neg;
uint8_t payload[128];
uint16_t crc;
};
Opening and configuring port:
HANDLE portHandler = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
DCB config = { 0 };
COMMTIMEOUTS timeout = { 0 };
// Configure
config.DCBlength = sizeof(config);
GetCommState(portHandler, &config);
config.BaudRate = CBR_115200;
config.ByteSize = 8;
config.StopBits = ONESTOPBIT;
config.Parity = NOPARITY;
SetCommState(portHandler, &config);
timeout.ReadIntervalTimeout = 50;
timeout.ReadTotalTimeoutConstant = 50;
timeout.ReadTotalTimeoutMultiplier = 50;
timeout.WriteTotalTimeoutConstant = 50;
timeout.WriteTotalTimeoutMultiplier = 10;
SetCommTimeouts(portHandler, &timeout);
Prepare module for XMODEM transfer:
DWORD toRead = 1;
DWORD wasWriten = 0;
DWORD wasRead = 0;
char responce = 0;
WriteFile(portHandler, "set load xmodem\n", 3+4+6+3, &wasWriten, NULL);
WriteFile(portHandler, "\n", 2, &wasWriten, NULL); // Doesn't work without this
Construct XMODEM frame
xmodem_frame frame;
frame.start = SOH;
frame.block = 0;
frame.block_neg = 0;
memcpy(frame.payload, "test_data", 128);
swap16(crc16(frame.payload, sizeof(frame.payload)));
Send frame and look for ACK:
WriteFile(portHandler, &frame, sizeof(frame), &wasWriten, NULL);
ReadFile(portHandler, &responce, toRead, &wasRead, NULL);
if (responce == 6)
std::cout << "ACK was recieved";
else
std::cout << "ACK wasn't recieved";
I was expecting to get an ACK, however "ACK wasn't recieved" is always printed.
I am trying to implement fast IO under Windows, and working my way up to Overlapped IO. In my research, Unbuffered IO requires page aligned buffers. Ive attempted to implement this in my code below. However, I occasionally have Readfiles last error report no access (error 998, ERROR_NOACCESS) - prior to completing the read, and after a few reads of a page aligned buffer. Sometimes 16. Sometimes 4, etc.
I cant for the life of me figure out why i am occasionally throwing an error. Any insight would be helpful.
ci::BufferRef CinderSequenceRendererApp::CreateFileLoadWinNoBufferSequential(fs::path path) {
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (file == INVALID_HANDLE_VALUE)
{
console() << "Could not open file for reading" << std::endl;
}
ci::BufferRef latestAvailableBufferRef = nullptr;
LARGE_INTEGER nLargeInteger = { 0 };
GetFileSizeEx(file, &nLargeInteger);
// how many reads do we need to fill our buffer with a buffer size of x and a read size of y
// Our buffer needs to hold 'n' sector sizes that wil fit the size of the file
SYSTEM_INFO si;
GetSystemInfo(&si);
long readAmount = si.dwPageSize;
int numReads = 0;
ULONG bufferSize = 0;
// calculate sector aligned buffer size that holds our file size
while (bufferSize < nLargeInteger.QuadPart)
{
numReads++;
bufferSize = (numReads) * readAmount;
}
// need one page extra for null if we need it
latestAvailableBufferRef = ci::Buffer::create(bufferSize + readAmount);
if (latestAvailableBufferRef != nullptr)
{
DWORD outputBytes = 1;
// output bytes = 0 when OEF
void* address = latestAvailableBufferRef->getData();
DWORD bytesRead = 0;
while (outputBytes != 0)
{
bool result = ReadFile(file, address, readAmount, &outputBytes, 0);
if (!result )//&& (outputBytes == 0))
{
getLastReadError();
}
address = (void*)((long)address + readAmount);
bytesRead += outputBytes;
}
}
CloseHandle(file);
// resize our buffer to expected file size?
latestAvailableBufferRef->resize(nLargeInteger.QuadPart);
return latestAvailableBufferRef;
}
Cast to long long - I was truncating my pointer address. Duh. Thanks to #jonathan-potter
I am trying to write some data to an SD card from a specific physical sector. I received a code to do this from a company and they say it works ok on windows-xp. This is the same case with WriteFile error #5 "denied access" under win Vista/seven
Here is the part writing the data to SD card (in my cae drv value is 'F'). Reading from others, I added locking and dismont but the lock fails (and dismount too). I'm not so familiar with windows programming. Can anybody tell me what's wrong in this code? Thanks for any help. (BTW I;m locking 3GiB)
u32 HDD_write(u8 drv, u32 SecAddr, u32 blocks, u8 *buf)
{
u32 ret = 0;
u32 ldistanceLow, ldistanceHigh, dwpointer, bytestoread, numread;
char cur_drv[100];
HANDLE g_hDevice;
sprintf(cur_drv, "\\\\.\\%c:",drv); // , (u32)drv);
g_hDevice = CreateFile(cur_drv, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(g_hDevice == INVALID_HANDLE_VALUE)
return 0;
// lock and dismount
ret = LockFile(g_hDevice, 0, 0, 3 * 1023 * 1023 * 1023, 0);
printf("ret = %d", ret);
DeviceIoControl(g_hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
printf("error = %d", GetLastError());
ldistanceLow = SecAddr << 9;
ldistanceHigh = SecAddr >> (32-9);
dwpointer = SetFilePointer(g_hDevice, ldistanceLow, (long *)&ldistanceHigh, FILE_BEGIN);
if(dwpointer != 0xFFFFFFFF) {
bytestoread = blocks * 512;
ret = WriteFile(g_hDevice, buf, bytestoread, (unsigned long *)&numread, NULL);
if(ret) ret = 1;
else {
ret = 0;
printf("error = %d", GetLastError());
}
}
CloseHandle(g_hDevice);
return ret;
}
I solved this problem several days ago and forgot to check my question here.
This is the code I used. We need GENERIC_READ also for block device when creating the file (for partitioned disk). and the key was dismount first and then lock.
u32 HDD_write(u8 drv, u32 SecAddr, u32 blocks, u8 *buf) {
u32 ret = 0;
u32 ldistanceLow, ldistanceHigh, dwpointer, bytestoread, numread;
char cur_drv[100];
HANDLE g_hDevice;
DWORD status;
//sprintf(cur_drv, "\\\\.\\PhysicalDrive%d", drv);
sprintf(cur_drv, "\\\\.\\%c:",drv);
g_hDevice = CreateFile(cur_drv, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(g_hDevice == INVALID_HANDLE_VALUE)
return 0;
// dismout and lock added by ckim
if (!DeviceIoControl(g_hDevice, FSCTL_DISMOUNT_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
DWORD err = GetLastError();
printf("Error %d attempting to dismount volume, error code\n",err);
}
// lock volume
if (!DeviceIoControl(g_hDevice, FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
printf("Error %d attempting to lock device\n", GetLastError());
}
ldistanceLow = SecAddr << 9;
ldistanceHigh = SecAddr >> (32-9);
dwpointer = SetFilePointer(g_hDevice, ldistanceLow, (long *)&ldistanceHigh, FILE_BEGIN);
if(dwpointer != 0xFFFFFFFF) {
bytestoread = blocks * 512;
ret = WriteFile(g_hDevice, buf, bytestoread, (unsigned long *)&numread, NULL);
if(ret) ret = 1;
else {
ret = 0;
printf("error = %d", GetLastError());
}
}
CloseHandle(g_hDevice);
return ret;
}
The content of the '.text' section is accessed using code like this:
1) For the application which is loaded into memory (i.e. executing):
//accessing code in memory
PIMAGE_DOS_HEADER pDOSHeader = NULL;
pDOSHeader = static_cast<PIMAGE_DOS_HEADER>( (void*)hModule);
...
PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>((byte*)hModule + pDOSHeader->e_lfanew );
...
PIMAGE_FILE_HEADER pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>((byte*)&pNTHeader->FileHeader );
...
PIMAGE_OPTIONAL_HEADER pOptionalHeader =
reinterpret_cast<PIMAGE_OPTIONAL_HEADER>((byte*)&pNTHeader->OptionalHeader );
...
PIMAGE_SECTION_HEADER pSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
(byte*)&pNTHeader->OptionalHeader +
pNTHeader->FileHeader.SizeOfOptionalHeader );
//so iterate headers and select one with right name
const char TEXT[] = ".text";
const char BSSTEXT[] = ".textbss";
unsigned int nSectionCount = pNTHeader->FileHeader.NumberOfSections;
char szSectionName[ IMAGE_SIZEOF_SHORT_NAME + 1 ];
szSectionName[ IMAGE_SIZEOF_SHORT_NAME ] = '\0';
for( unsigned int i = 0; i < nSectionCount; i++ )
{
memcpy( szSectionName, pSectionHeader->Name,
IMAGE_SIZEOF_SHORT_NAME );
if( 0 == strncmp( TEXT, szSectionName,
IMAGE_SIZEOF_SHORT_NAME ) )
{
break;
}
pSectionHeader++;
}
pVirtualAddress = (void*)(pSectionHeader->VirtualAddress);
dwCodeSize = pSectionHeader->Misc.VirtualSize;
//seems resonable: To calculate the real starting address of a given section in memory,
//add the base address of the image to the section's VirtualAddress stored in this field.
pCodeStart = (void*)(((byte*)hModule) +(size_t)((byte*)pVirtualAddress) );
pCodeEnd = (void*)((byte*)pCodeStart + dwCodeSize);
2) For the application file read from hdd and mapped into memory:
//loading code from file and mapping
hFile = CreateFile( filename, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
...
hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY ),0, 0, NULL );
...
pBaseAddress = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 );
...
PIMAGE_DOS_HEADER pDOSHeader = static_cast<PIMAGE_DOS_HEADER>( pBaseAddress);
...
PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
(PBYTE)_pBaseAddress() + pDOSHeader->e_lfanew );
...
PIMAGE_FILE_HEADER pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>(
(PBYTE)&pNTHeader->FileHeader );
...
PIMAGE_OPTIONAL_HEADER pOptionalHeader =
reinterpret_cast<PIMAGE_OPTIONAL_HEADER>(
(PBYTE)&pNTHeader->OptionalHeader );
PIMAGE_SECTION_HEADER pSectionHeader =
reinterpret_cast<PIMAGE_SECTION_HEADER>(
(PBYTE)&pNTHeader->OptionalHeader +
pNTHeader->FileHeader.SizeOfOptionalHeader );
DWORD dwEntryPoint = pNTHeader->OptionalHeader.AddressOfEntryPoint;
UINT nSectionCount = pNTHeader->FileHeader.NumberOfSections;
const char TEXT[] = ".text";
const char BSSTEXT[] = ".textbss";
char szSectionName[ IMAGE_SIZEOF_SHORT_NAME + 1 ];
szSectionName[ IMAGE_SIZEOF_SHORT_NAME ] = '\0';
for( unsigned int i = 0; i < nSectionCount; i++ )
{
memcpy( szSectionName, pSectionHeader->Name,
IMAGE_SIZEOF_SHORT_NAME );
if( 0 == strncmp( TEXT, szSectionName,
IMAGE_SIZEOF_SHORT_NAME ) )
{
break;
}
pSectionHeader++;
}
// Use this when probing On Disk. It is where things
// are on disk - not where they will be in memory
dwRawData = pSectionHeader->PointerToRawData;
// Use this when probing On Disk. It is where things
// are on disk - not where they will be in memory
pCodeStart = (void*)((byte*)pBaseAddress +
pSectionHeader->PointerToRawData );
pEntryPoint = (void*)(((byte*)pBaseAddress) + dwEntryPoint);
dwCodeSize = pSectionHeader->Misc.VirtualSize;
pCodeEnd = (void*)((byte*)pCodeStart + pSectionHeader->Misc.VirtualSize );
If the application is built with Visual Studio, all the bytes between pCodeStart and pCodeEnd are matching in both cases.
But if the application is built with GCC (MinGW) some bytes which are following pCodeStart and prior pCodeEnd are the same but somewhere in the middle some different bytes are appearing.
Why does it happen?
int main(int argc, char* argv[]) {
ofstream file;
file.open("Motion.dat");
int frame_number = 0;
CvCapture* capture = cvCreateFileCapture("Cricketc1.avi");
CvCapture* capture1 = cvCreateFileCapture("Cricketc1.avi");
IplImage* imgsize = NULL;
IplImage *img1 = NULL;
IplImage *img2 = NULL;
IplImage *vidFrame = NULL;
IplImage *imggray1 = NULL;
IplImage *imggray2 = NULL;
IplImage *imggray3 = NULL;
cvNamedWindow("Video", 0);
cvNamedWindow("Video1", 0);
imgsize = cvQueryFrame(capture1);
assert(imgsize);
CvSize sz = cvGetSize(imgsize);
cvReleaseCapture(&capture1);
imggray1 = cvCreateImage(sz, IPL_DEPTH_8U, 1);
imggray2 = cvCreateImage(sz, IPL_DEPTH_8U, 1);
imggray3 = cvCreateImage(sz, IPL_DEPTH_8U, 1);
while (true) {
frame_number++;
img1 = cvQueryFrame(capture);
if(img1->imageData == NULL)
break;
cvCvtColor(img1, imggray1, CV_RGB2GRAY);
img2 = cvQueryFrame(capture);
if(img2->imageData == NULL)
break;
cvCvtColor(img1, imggray1, CV_RGB2GRAY);
cvAbsDiff( imggray1, imggray2, imggray3 );
CvScalar sumDiff = cvSum (imggray3);
cout << sunDiff.val[0] << sunDiff.val[1] << sunDiff.val[2] << endl;
cvWaitKey(40);
}
cvReleaseCapture(&capture);
cvDestroyAllWindows();
file.close();
system("Pause");
return 0;
}
There are a total of 1251 frames in the video # 25 fps.
But the loop breaks at frame_number equal to 625, at line if(img2->imageData == NULL).
This error mainly comes up if I do any computation in between the while loop. A simple cvShowImage() will work just fine, but any other manipulation around it causes this error to show up.
This is the error that comes up after that :
Unhandled exception at 0x00221de7 in getMotion2.exe: 0xC0000005: Access violation reading location 0x00000044.
What is the problem ?
You are reading image twice from the same cvCapture* in a loop: img1 = cvQueryFrame(capture); and img2 = cvQueryFrame(capture);. If you change the second line to img2 = cvQueryFrame(capture2); it should work fine.