• C

Sending image to browser

I am writting a web server. i can send a htm/text etc fine but images stuff up.

does any body know how to read in a .gif/.jpg in C and then send it to a browser. what data type do i read the image into. at the moment im using an array of char (1 byte)

ill explain some more if nessecry
LVL 10
makerpAsked:
Who is Participating?
 
mouattsCommented:
Don't do strlen + 1 becuase that sends the null character which will 'corrupt' the image header by shifting everything one byte.

Steve

0
 
feenixCommented:
Have you remembered to send the appropriate header? You need to output the content-type -header and set it as image/jpeg or image/gif. Then just output the image as binary and you should be ok.
0
 
makerpAuthor Commented:
Adjusted points from 100 to 150
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 
makerpAuthor Commented:
yes. ther headers are fine. i think that problem lies in the char array that i read the binary into... any code examples
0
 
feenixCommented:
How about:

char buf[1000];
FILE *in;
int i;

in = fopen("image.gif", "rb");
while ((i = fread(buf, 1000, 1, in)))
  fwrite(buf, i, 1, stdout);

The code reads the file 100 bytes max at a time and outputs the data to stdout.
0
 
xLsCommented:
// this is a sample out of my 2 year old http server that works excelent :)




void CHttpServer::SendHTTP(Socket *s, HttpHeader* pHeader, const char* filename)
{
      char* buffer;
      char* SendBuf;
      char header[1024];
      char content[50];
      int i = 0;

      strcpy(content,GetContentType(filename));
      FILE *f = fopen(filename,"rb");
      if(f != NULL)
      {
            // Get size of file
            fseek( f, 0, SEEK_END);
            int fsize = ftell(f);
            fseek( f, 0, SEEK_SET);

            buffer = new char[fsize+1];
            int size = fread(buffer, sizeof(char), fsize, f);
            pHeader->m_HeaderStruct.Content_Length  = size;
            strcpy(pHeader->m_HeaderStruct.Content_Type,content);
            int headsize = pHeader->GetHeader(header, 1024);
            SendBuf = new char[headsize + size + 1];
            memcpy(SendBuf,header,headsize);
            memcpy(&SendBuf[headsize],buffer,size);
            s->Send(SendBuf,headsize + size);
            LOGSENDN(SendBuf,(headsize+size));
      
            delete [] SendBuf;
            delete [] buffer;
            fclose(f);
      }
      else
      {
            pHeader->m_HeaderStruct.Content_Length  = 0;
            int headsize = pHeader->GetHeader(header, 1024);
            s->Send(header,headsize );
            LOGSENDN(header,headsize);
      }
      

}


basically check file size. build header with correct content and size of content.

remember to read also using binary since a IMG file can and always has EOF characters everywhere.

otherwise its not any different from your normal html packages.


if you need some hints about HTTP servers, you can ask me. mine is only 22k and quite small but fully functional even using CGI.

Good luck on you
/T. Rizos
0
 
makerpAuthor Commented:
this is the function i use to read the file in. if its jpg/gif the binary mode is switched on. i return the text array and then send it but it dont work. i put the content-type and lenght out followed by two newlines.

your code uses C++ and this is all C so far which is how i would like to keep it..

can you see a problem with this function ??


char *fetchFile(char *file_name, int read_mode)
{
      long flen = 0, f = 0;
      char *text = NULL;
      int fhandle;

      fhandle = sopen(file_name, O_RDONLY|O_TEXT,SH_DENYNO);
      if(fhandle > -1)
      {
            if(read_mode == BINARY_ON)
            {
                  _setmode(fhandle,_O_BINARY);
            }
            f = filelength(fhandle);
            text = malloc(f+1);
            if(text)
            {
                  flen = read(fhandle,text,f);
                  text[flen] = '\0';
            }
            close(fhandle);
      }
      return text;
}



this is the code that requests the file etc
if((mime =  getMimeType(filepath)) != NULL)
                                    {
                                          if(!strcmp("image/jpeg",mime) || !strcmp("image/gif",mime))
                                          {
                                                read_mode = BINARY_ON;
                                          }
                                          if((file = fetchFile(filepath,read_mode)) != NULL)
                                          {
                                                sprintf(buffer,"HTTP/1.0 200\nContent-type: %s\nContent-length: %i\n\n",mime,strlen(file) + 1);
                                                send(client,buffer,strlen(buffer) + 1,0);
                                                send(client,file,strlen(file),0);
                                                free(file);
                                          }
                                          else
                                          {
                                                sendError(client,HTTP_404,HTTP_404_STRING);
                                          }
                                          free(mime);

0
 
makerpAuthor Commented:
sorry must reject this awnser so others respond...

thanx anyway
0
 
xLsCommented:
Thats all right makerp, Could you just check if _setmode(..); doesnt return -1;


ah, when you send the file
you use strlen() to get the size of the buffer.

send(client,buffer,strlen(buffer) + 1,0);
send(client,file,strlen(file),0);


instead in your fetchfile().. add a parameter int* which returns the size of the buffer(which you get from filelength).

strlen counts amount of characters untill the NULL Char, an image can have several NULL's anywhere.



first make sure that fetchfile actually reads the complete file, make sure that _setmode is successful.


Hope this will make it happen/good luck

/T. Rizos

0
 
makerpAuthor Commented:
ive got it working now it was because i was corrupting the image output andu using strlen (i now use _msize(pointer))...

mouatts fixed it for me so im affraid ill have to award the points to him.

but i shall post a blank question for you.

0
 
makerpAuthor Commented:
thanx captin......

all left now is cgi.....

emmmmm fun ??
0
 
xLsCommented:
Doh, missed that :D

cheers
PS: cgi is easy:D
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.