Open an image (jpg, gif, xbm) in binary mode - html

I'm working on a server/client assignment. My server should pass down to Client HTML, .txt, .jpg, .gif, and .xbm files to open up on a web browser when I go the localhost:8080/some address... my HTML and .txt files open like a charm! however the .jpg and .gif wont display at all. the server does locate the file but when it comes to reading or displaying the .jpg or .gif it cannot be display because it contains errors, but when I open it in a regular browser it works good. Our instructions are "When you open an image file for reading, make sure to open it in binary mode, since an image file contains binary data." so I did just that but since the image is not displaying I wonder if I'm doing it correctly. Here is my code in c to read a file that I use for html, txt, and image formats.
void file_read(char *filename){
//filename is actually the path
size_in = strlen(filename);
//this is test display to see how the path was being read and since getting a
//from a web browser contains an extra character '/' in the beginning we need to
//to ignore it,
printf("printf in file_read function %d\n", size_in);
wtg = filename + 1;
printf("printf in file_read function %s\n", wtg);
//file open and transfer in binary 'rb'
fp= fopen (wtg, "rb");
if (fp == NULL){
printf("Could not open the file\n");
exit(0);
}
fseek(fp , 0, SEEK_END);
len = ftell (fp);
rewind (fp);
//allocate memory to contain the whole file:
linehtml = calloc(1, len + 1);
if (linehtml == NULL){fputs("Memory Error", stderr);
exit(2);}
//copy the file into the buffer:
if(1!=fread(linehtml, len, 1, fp)){
fputs("entire read fails",stderr),exit(1);
}
fclose(fp);
/*if (result != len) {
printf("file lenght is %d\n\n", len);
fputs ("Reading Error",stderr);
exit(3);
};*/
}
Is there something wrong? is the buffer not long enough? any ideas?

Related

Is there a standard way to add textual information in a TIFF file with FreeImage?

I have a program that generates its results as TIFF files. I would like to add some textual information in theses files to keep a trace of the program parameters.
I know that a tag named "ImageDescription" can be added in a tiff file (according to the specification file p34), if I could put the program parameters in that field, it will be ok for me.
But is it possible to set this tag with FreeImage?
If it's not possible, can I add EXIF information to my tiff file with FreeImage?
I answer my own question.
With FreeImage, one simple way to add metadata is to use IPTC tags:
void addTag(FIBITMAP *bitmap, const char *key, const char *value)
{
FITAG *tag = FreeImage_CreateTag();
size_t len = strlen(value)+1;
FreeImage_SetTagKey(tag, len);
FreeImage_SetTagCount(tag, len);
FreeImage_SetTagType(tag, FIDT_ASCII);
FreeImage_SetTagValue(tag, value);
FreeImage_SetMetadata(FIMD_IPTC, bitmap, FreeImage_GetTagKey(tag), tag);
FreeImage_DeleteTag(tag);
}
And, use these function with valid IPTC tags:
// set creator's name, limited to 32 bytes
addTag(bitmap, "By-line", "Creator's name");
// set keyword, limited to 64 bytes
addTag(bitmap, "Keywords", "Param1=foo;Param2=bar");
I would like to modify Mathieve's answer little bit. Otherwise it will not work.
void addTag(FIBITMAP *bitmap, const char *key, const char *value)
{
FITAG *tag = FreeImage_CreateTag();
if(tag)
{
size_t len = strlen(value)+1;
FreeImage_SetTagKey(tag, len);
//Tag length, tag count and tag type should be set before setting tag value
FreeImage_SetTagLength(tag, len);
FreeImage_SetTagCount(tag, len);
FreeImage_SetTagType(tag, FIDT_ASCII);
FreeImage_SetTagValue(tag, value);
FreeImage_SetMetadata(FIMD_IPTC, bitmap, FreeImage_GetTagKey(tag), tag);
//Delete tag after setting the metadata
FreeImage_DeleteTag(tag);
}
}
And, use these function with valid IPTC tags in FreeImage documentation:
// set creator's name, limited to 32 bytes
addTag(bitmap, "By-line", "Creator's name");
// set keyword, limited to 64 bytes
addTag(bitmap, "Keywords", "Param1=foo;Param2=bar");

Write a CSV file in Shift-JIS (MFC VC++, Windows Embedded - WinCE)

As the title says, I have been trying to write data that the user enters into a CEdit control to a file.
The system is a handheld terminal running Windows CE, in which my test application is running, and I try to enter test data (Japanese characters in Romaji, Hiragana, Katakana and Kanji mixed along with normal English alphanumeric data) that initially is displayed in a CListCtrl. The characters display properly on the handheld display screen in my test application UI.
Finally, I try to read back the data from the List control and write it to a text CSV file. The data I get on reading back from the control is correct, but on writing it to the CSV, things mess up and my CSV file is unreadable and shows strange symbols and nonsense alphanumeric garbage.
I searched about this, and I ended up with a similar question on stackOverflow:
UTF-8, CString and CFile? (C++, MFC)
I tried some of their suggestions and finally ended up with a proper UTF-8 CSV file.
The write-to-csv-file code goes like this:
CStdioFile cCsvFile = CStdioFile();
cCsvFile.Open(cFileName, CFile::modeCreate|CFile::modeWrite);
char BOM[3]={0xEF, 0xBB, 0xBF}; // Utf-8 BOM
cCsvFile.Write(BOM,3); // Write the BOM first
for(int i = 0; i < M_cDataList.GetItemCount(); i++)
{
CString cDataStr = _T("\"") + M_cDataList.GetItemText(i, 0) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 1) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 2) + _T("\"\r\n");
CT2CA outputString(cDataStr, CP_UTF8);
cCsvFile.Write(outputString, ::strlen(outputString));
}
cCsvFile.Close();
So far it is OK.
Now, for my use case, I would like to change things a bit such that the CSV file is encoded as Shift-JIS, not UTF-8.
For Shift-JIS, what BOM do I use, and what changes should I make to the above code?
Thank you for any suggestions and help.
Codepage for Shift-JIS is apparently 932. Use WideCharToMultiByte and MultiByteToWideChar for conversion. For example:
CStringW source = L"日本語ABC平仮名ABCひらがなABC片仮名ABCカタカナABC漢字ABC①";
CStringA destination = CW2A(source, 932);
CStringW convertBack = CA2W(destination, 932);
//Testing:
ASSERT(source == convertBack);
AfxMessageBox(convertBack);
As far as I can tell there is no BOM for Shift-JIS. Perhaps you just want to work with UTF16. For example:
CStdioFile file;
file.Open(L"utf16.txt", CFile::modeCreate | CFile::modeWrite| CFile::typeUnicode);
BYTE bom[2] = { 0xFF, 0xFE };
file.Write(bom, 2);
CString str = L"日本語";
file.WriteString(str);
file.Close();
ps, according to this page there are some problems between codepage 932 and Shift-JIS, although I couldn't duplicate any errors.

CGI wont display variables through HTML in c (Eclipse)

I have used a fifo pipe to read in some data (weather data) into a char variable. The console will display this variable correctly. However, when I try to display it through HTML on the CGI page, it simply does not display. Code below -
int main(void) {
int fd;
char *myfifo = "pressure.txt";
char buff[BUFFER];
long fTemp;
//open and read message
fd = open(myfifo, O_RDONLY);
read(fd, buff, BUFFER);
printf("Received: %s\n", buff);
close(fd);
printf("Content-type: text/html\n\n");
puts("<HTML>");
puts("<BODY>");
printf("Data is: %s", buff);
puts("</BODY>");
puts("</HTML>");
return EXIT_SUCCESS;
}
As you can see in the console is displays correctly -
Received: 2014-08-13 16:54:57
25.0 DegC, 1018.7 mBar
Content-type: text/html
<HTML>
<BODY>
Data is 2014-08-13 16:54:57
25.0 DegC, 1018.7 mBar
</BODY>
</HTML>
logout
But on the CGI webpage it does not display the weather data, but it does display "data is".
Two important things when writing a CGI program:
the program will be run by the webserver, which is normally
started as a different user (the 'www' user for example).
it's possible that the program is started from within another
directory, which can cause different behaviour if you don't
specify the full path of a file you want to open.
Since both these things can cause problems, it can be helpful
to add some debug information. Of course, it's always a good idea
to check return values of functions you use.
To make it easier to display debug or error messages, I'd first
move the following code up, so that all output that comes after
it will be rendered by the browser:
printf("Content-type: text/html\r\n\r\n");
puts("<HTML>");
puts("<BODY>");
It may be useful to know what the webserver uses as the directory
from which the program is started. The getcwd
call can help here. Let's use a buffer of size BUFFER to store
the result in, and check if it worked:
char curpath[BUFFER];
if (getcwd(curpath, BUFFER) == NULL)
printf("Can't get current path: %s<BR>\n", strerror(errno));
else
printf("Current path is: %s<BR>\n", curpath);
The getcwd function returns NULL in case of an error, and sets the value
of errno to a number which indicates what went wrong. To convert this
value to something readable, the strerror
function is used. For example, if BUFFER was not large enough to be
able to store the path, you'll see something like
Can't get current path: Numerical result out of range
The open call returns a negative number
if it didn't work, and sets errno again. So, to check if this worked:
fd = open(myfifo, O_RDONLY);
if (fd < 0)
printf("Can't open file: %s<BR>\n", strerror(errno));
In case the file can be found, but the webserver does not have permission
to open it, you'll see
Can't open file: Permission denied
If the program is started from another directory than you think, and
it's unable to locate the file, you would get:
Can't open file: No such file or directory
Adding such debug info should make it more clear what's going on, and more
importantly, what's going wrong.
To make sure the actual data is read without problems as well, the return
value of the read function should be
checked and appropriate actions should be taken. If read fails,
a negative number is returned. To handle this:
numread = read(fd, buff, BUFFER);
if (numread < 0)
printf("Error reading from file: %s<BR>\n", strerror(errno));
Another value indicates success, and returns the number of bytes that were
read. If really BUFFER bytes were read, it's not at all certain that the
last byte in buff is a 0, which is needed for printf to know when the
string ended. To make sure it is in fact null-terminated, the last byte in
buff is set to 0:
if (numread == BUFFER)
buff[BUFFER-1] = 0;
Note that this actually overwrites one of the bytes that were read in this
case.
If fewer bytes were read, it's still not certain that the last byte that was
read was a 0, but now we can place our own 0 after the bytes that were read
so none of them are overwritten:
else
buff[numread] = 0;
To make everything work, you may need the following additional include files:
#include <unistd.h>
#include <string.h>
#include <errno.h>
The complete code of what I described is shown below:
int main(void)
{
int fd, numread;
char *myfifo = "pressure.txt";
char buff[BUFFER];
char curpath[BUFFER];
long fTemp;
// Let's make sure all text output (even error/debug messages)
// will be visible in the web page
printf("Content-type: text/html\r\n\r\n");
puts("<HTML>");
puts("<BODY>");
// Some debug info: print the current path
if (getcwd(curpath, BUFFER) == NULL)
printf("Can't get current path: %s<BR>\n", strerror(errno));
else
printf("Current path is: %s<BR>\n", curpath);
// Open the file
fd = open(myfifo, O_RDONLY);
if (fd < 0)
{
// An error occurs, let's see what it is
printf("Can't open file: %s<BR>\n", strerror(errno));
}
else
{
// Try to read 'BUFFER' bytes from the file
numread = read(fd, buff, BUFFER);
if (numread < 0)
{
printf("Error reading from file: %s<BR>\n", strerror(errno));
}
else
{
if (numread == BUFFER)
{
// Make sure the last byte in 'buff' is 0, so that the
// string is null-terminated
buff[BUFFER-1] = 0;
}
else
{
// Fewer bytes were read, make sure a 0 is placed after
// them
buff[numread] = 0;
}
printf("Data is: %s<BR>\n", buff);
}
close(fd);
}
puts("</BODY>");
puts("</HTML>");
return EXIT_SUCCESS;
}

HTML5 File API - slicing or not?

There are some nice examples about file uploading at HTML5 Rocks but there are something that isn't clear enough for me.
As far as i see, the example code about file slicing is getting a specific part from file then reading it. As the note says, this is helpful when we are dealing with large files.
The example about monitoring uploads also notes this is useful when we're uploading large files.
Am I safe without slicing the file? I meaning server-side problems, memory, etc. Chrome doesn't support File.slice() currently and i don't want to use a bloated jQuery plugin if possible.
Both Chrome and FF support File.slice() but it has been prefixed as File.webkitSlice() File.mozSlice() when its semantics changed some time ago. There's another example of using it here to read part of a .zip file. The new semantics are:
Blob.webkitSlice(
in long long start,
in long long end,
in DOMString contentType
);
Are you safe without slicing it? Sure, but remember you're reading the file into memory. The HTML5Rocks tutorial offers chunking the upload as a potential performance improvement. With some decent server logic, you could also do things like recovering from a failed upload more easily. The user wouldn't have to re-try an entire 500MB file if it failed at 99% :)
This is the way to slice the file to pass as blobs:
function readBlob() {
var files = document.getElementById('files').files;
var file = files[0];
var ONEMEGABYTE = 1048576;
var start = 0;
var stop = ONEMEGABYTE;
var remainder = file.size % ONEMEGABYTE;
var blkcount = Math.floor(file.size / ONEMEGABYTE);
if (remainder != 0) blkcount = blkcount + 1;
for (var i = 0; i < blkcount; i++) {
var reader = new FileReader();
if (i == (blkcount - 1) && remainder != 0) {
stop = start + remainder;
}
if (i == blkcount) {
stop = start;
}
//Slicing the file
var blob = file.webkitSlice(start, stop);
reader.readAsBinaryString(blob);
start = stop;
stop = stop + ONEMEGABYTE;
} //End of loop
} //End of readblob

Scraped HTML is not written at the beginning of text file

Currently, I'm scraping the HTML code of a page, and writing it to a text file.
My problem is, why must there be empty spaces or empty lines at the beginning? The HTML codes written to the txt file do not seem to start at the beginning of the text file. This means that the '<' is not located at the position 0 of the txt file.
After a few runs, my HTML is always written a few lines down inside the text file.
Can anyone tell me why?
Below is my code. I'm doing it under Visual C++ .
UINT32 LOG(wstring log, UINT32 flag)
{
wfstream file (LOG_FILE, ios_base::app);
file << log;
file.close();
return 1;
}
My problem is, the HTML code copied to my text file is always down a couple of lines, then will find the '<' tag. What I want is, the HTML's first '<' is written at the position 0 of my text file :)
Below is my code. I'm doing it under Visual C++ .
UINT32 LOG(wstring log, UINT32 flag)
{
if(flag == 0)
{
wfstream file (LOG_FILE, ios_base::app);
if (file.is_open())
{
file << log <<endl;
file.close();
wcout << endl << log << endl;
return 0;
}
else wcout << "\nUnable to open LOG file\n";
return 1;
}
My problem is, the HTML code copied to my text file is always down a couple of lines, then will find the '<' tag. What I want is, the HTML's first '<' is written at the position 0 of my text file :)