Saving PNG file in console program -- losing data

Jul 18, 2013 at 7:38pm
I am working on a project that uses a web service to extract a PNG image from a web server and save it on a local machine. It's done via a system call. I can get the output of the system call to a FILE but it appears to be losing data, most notably the PNG chunk names (IHDR/PLTE/IDAT/IEND, notably). (Unfortunately piping the output to an exterior file does not work through a system call.) The end result is ~6KB smaller than the file I am intending to retrieve.

This is the code I'm using (adapted from other material I found via searches here):

1
2
3
4
5
6
7
8
9
10
11
12
13
ofstream png;
png.open(/*outputfile*/, ios::binary);
FILE* fp = _popen(/*SYSTEMCALL*/, "rb");
string responseString;
if(fp != NULL) {
  char a[100];
  while(!feof(fp)) {
    fgets(a, 100, fp);
    responseString += a;
  }
}
_pclose(fp);
png << responseString;


Am I missing something or just doing it wrong?
Jul 18, 2013 at 7:41pm
closed account (Dy7SLyTq)
i would use sdl with the SDL_image extension
Jul 18, 2013 at 9:44pm
OP: ¿what if you read a '\0' ?
Jul 19, 2013 at 1:59pm
@ne555: That might be an issue as well. I haven't done a full file comparison but there's enough missing that '\0's are probably being blocked out as well. Maybe I'll try using read()...

@DTSCode: All I want to do is copy the file returned from the web surface to a local file; I don't want to display it or anything like that. Can I do that with SDL? (I'm a bit of a novice when it comes to image processing.)
Jul 19, 2013 at 2:16pm
closed account (Dy7SLyTq)
yeah sdl is great with image processing.
Jul 19, 2013 at 2:51pm
But SDL doesn't have functions for saving PNG files.
Jul 19, 2013 at 2:52pm
closed account (Dy7SLyTq)
with the SDL_image extension

that does though
Jul 19, 2013 at 2:58pm
while(!feof(fp)) is wrong (it is pointless to test for input errors before the input is even attempted!)
responseString += a; stops at the first zero found in a
Jul 19, 2013 at 2:59pm
@DTSCode: For loading yes, but not for saving.

If I understand correctly the OP just want to transfer a PNG file from a web server to the local machine. You don't need any PNG-specific code for doing that.
Last edited on Jul 19, 2013 at 3:00pm
Jul 19, 2013 at 3:53pm
If I understand correctly the OP just want to transfer a PNG file from a web server to the local machine. You don't need any PNG-specific code for doing that.

Exactly this. Just looking at some of the SDL stuff it doesn't look like where I want to go.

The service returns the contents of the PNG file itself, so ideally I just want to copy that and save it to a file.

@Cubbi: Would it be better to use a char [] array instead?
Jul 19, 2013 at 4:06pm
You already have a char array, a. Why not fread into it and, if you want the output to be a C++ stream, ostream::write straight from a?
1
2
3
4
5
6
7
8
    std::ofstream png("test.out", std::ios::binary);
    if(FILE* fp = popen("cat /bin/ls", "r"))  {
        char a[100];
        while(int n = std::fread(a, 1, sizeof a, fp))
            png.write(a, n);
        pclose(fp);
    }  else
            perror("popen failed");

(I don't have windows, so popen doesn't accept "rb" for me)
Last edited on Jul 19, 2013 at 4:06pm
Jul 19, 2013 at 6:52pm
I hadn't thought about fread! Just tried out this version and I'm getting what I want now. Thanks a bunch!
Topic archived. No new replies allowed.