Receiving JPEG packet from camera

I am trying to receive a packet of data as bytes in C, but the picture is getting messed up.

I am using fwrite to append bytes to jpg file, but the append or write does not
seem to be appending jpg correctly.

Packet 1 data comes in append to file
Packet 2 data comes in append to file
...
N packets

void BWrite(unsigned char *b){
    FILE *fp;
    fp = fopen(filename, "ab");
    fwrite(b,1,1,fp);
    fclose(fp);
}

The computer runs centos on flash hard drive.

My brain is fried and out of ideas on how to get this JPEG looking right instead of as bad looking jigsaw puzzle :confused:

You're not using the file I/O buffering that fopen gives you, so you may as well use open, which will be quicker...try:

void BWrite(unsigned char *b){
    int fd;
    fd=open(filename,O_CREAT|O_APPEND,0700);
    write(fd,b,1);
    close(fd);
}

Thanks for reply.

OK, that created the file, but left file empty with 0 bytes.

Any other ideas, my brain hurts.:confused:

Also, JPEG is Big-Endian and my CentOS is Little-Endian, so I was trying to
see if reversing the char would correct, but have been unsuccessful so far.
Not sure if this is correct path to fix problem or if writing to disk is problem.

Open to any suggestions, thanks.

---------- Post updated at 11:09 AM ---------- Previous update was at 10:49 AM ----------

Changing your code to:

void BWrite(unsigned char *b){
    FILE *fd;
    fd=fopen(filename,"ab+");
    write(fd,b,1);
    fclose(fd);
}

wrote to file, but it is not opening as jpg file still???

You can't mix fopen and write() calls. fopen belongs with fwrite, open belongs with write.

Your first code wasn't wrong, either. It looks like it should write one more byte onto the end of the file.

I think what's wrong is the fact that you're writing single bytes. Are you sure your packets are single bytes? That seems really odd! You might be throwing out 99% of the packet.

I am getting all the data as bytes in packets.

What ways are there to wright data blocks of bytes?

Maybe 10 bytes a block.

Would this affect the JPEG image size, because all jpg files
have the same size, even when camera sends different size
images.

Of course you are. Anything chunk of data whatsoever can be represented as 8-bit bytes. But that doesn't mean you're getting only one byte!

You already know 2 different ways. The difference is that, instead of using them to write 1 byte, you use them to write more.

Do you actually know that? Do you know your packets are even all the same size? You shouldn't have to guess -- something, somewhere in your code must know the size of the packet you received, but you're either not keeping that result or not using it...

Unfortunately we can't see your code from here. Please post it.

I certainly hope it would affect the jpeg image size, right now they're only going to be a tiny fraction of the size they should be.

I don't have documentation that is the problem and I am forced to try and understand how to get this JPEG image correct.

Documentation does say image size is

0xNNMMZZYY - Image Size 32 bits

The data for example gives me:
NN=0
MM=0
ZZ=10
YY=64

I know how many data bytes total from the formula I calulated.
((zz - 1) * 259) + 256 + YY = DataSize for individual packets

Don't know what the formula means, but it works, so I tried to append
the bytes one by one, but got a fuzzy image and I know the camera works
because the older pascal code works and uses a Blockwrite function:

 Blockwrite(MyFileHandle, byte, 1, BytesRead);

which writes byte by byte in a loop, similar to the way I first explained and tried to emulate.

When looking at image properties in firefox, image size in not defined.

How do you specify the image size for file?

Here is some debug info from identify on jpeg header.

# identify -verbose 2010-12-21_09-21-29.jpg
Image: 2010-12-21_09-21-29.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Class: DirectClass
  Geometry: 320x240
  Type: TrueColor
  Endianess: Undefined
  Colorspace: RGB
  Channel depth:
    Red: 8-bits
    Green: 8-bits
    Blue: 8-bits
  Channel statistics:
    Red:
      Min: 0 (0)
      Max: 255 (1)
      Mean: 126.909 (0.497684)
      Standard deviation: 76.9182 (0.30164)
    Green:
      Min: 0 (0)
      Max: 208 (0.815686)
      Mean: 6.00544 (0.0235508)
      Standard deviation: 11.4396 (0.0448613)
    Blue:
      Min: 0 (0)
      Max: 255 (1)
      Mean: 8.88395 (0.034839)
      Standard deviation: 17.7563 (0.0696327)
  Colors: 1556
  Rendering intent: Undefined
  Resolution: 1029x1543
  Units: Undefined
  Filesize: 4.6kb
  Interlace: None
  Background color: white
  Border color: #DFDFDF
  Matte color: grey74
  Page geometry: 320x240+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 50
  Orientation: Undefined
  JPEG-Colorspace: 2
  JPEG-Sampling-factors: 2x2,1x1,1x1
  Signature: 7afd494edfe783dded28011ccd4d1405166cf6f193e1e58a0ec891ac53e2dc53
  Tainted: False
  Version: ImageMagick 6.2.8 10/20/10 Q16 file:/usr/share/ImageMagick-6.2.8/doc/index.html
identify: Corrupt JPEG data: 6 extraneous bytes before marker 0xc0 `2010-12-21_09-21-29.jpg'.
identify: Premature end of JPEG file `2010-12-21_09-21-29.jpg'.
identify: Corrupt JPEG data: premature end of data segment `2010-12-21_09-21-29.jpg'.

You don't need to research or guess the number of bytes. The operating system is quite probably telling you how many bytes you got from the camera, but you're not using it, or using it incorrectly. The parts of the code you've shown us, so far, have nothing to with reading the data, just writing it. For that matter, it's run in a loop which you've never shown us, which might have things wrong in it too.

None of the information on your corrupted output file will help tell us what's wrong in code we've never seen.

In short: We can't fix your code because you didn't show it to us. Please post your code. All of it.

code is to long to put, but I think problem is with bitstream and way it constructs jpeg.

using fread to fwrite from on jpeg to another jpeg works, but
I am using read from serial device and using fwrite to jpeg file,
which seems to be causing the stream problem.

basics of main code to grab packets as they come in from serial:

fd = open(DEVICE, O_RDWR | O_NOCTTY |O_NDELAY);
res = read(fd,buf, BUFSIZE);
buf[res] = 0;
parse(buf,res);

parse code for each packet is basically

void parse(unsigned char *buff, size_t ss){
  // puts it into a buffer and sends each byte to fwrite
  for(i=0;i < ss ; i++){
    b = buff;
    // case statement here
    //when packet has data from jpeg send
    BlockW(&b); 
  }
}
void BlockW(unsigned char *b){
  FILE *fp;
  fp = fopen(filename, "ab");
  fwrite(b, sizeof(unsigned char), sizeof(unsigned char), fp);
  fclose(fp);
}

I actually found a website that has the exact same corrupted looking jpeg pictures as the ones that are created from code.

ImpulseAdventure - Fix Corrupt JPEG Photos!

Seems to be a stream issue, how would I create the fread to fwrite stream using read to fwrite, which seems to not put the stream correctly.

That's a bit more helpful. You've opened the device with O_NDELAY, this means read might sometimes return -1, telling you to try again later. When this happens your code will still write something, even though it shouldn't.

You have to use read() for handling a device file.

int fd = open(DEVICE, O_RDWR | O_NOCTTY |O_NDELAY);
int out=open("outfile", O_CREAT|O_WRONLY, 0660);

while(1)
{
        ssize_t off=0;
        ssize_t res = read(fd,buf, BUFSIZE);
        // Ignore when read didn't get anything
        if(res < 0)
                continue;
        else if(res == 0) // should your app expect EOF?
        {
                fprintf(stderr, "EOF?\n");
                break;
        }

        fprintf(stderr, "Read %d bytes\n", (int)res);
        // buf[res] = 0; why null-terminate what's not a string?
        //parse(buf,res); we're not in pascal anymore

        // We can probably write everything at once.  when we don't,
        // just write the bits that didn't get written yet.
        while(off < res)
        {
                ssize_t w=write(outfd, buf+off, res-off);
                if(w > 0)
                        off += w;
                else
                {
                        perror("write error");
                        break;
                }
                fprintf(stderr, "Wrote %d bytes\n", (int)w);
        }
}

close(out);
close(fd);

In summary: Always check the return value of everything.

Problem Solved

Packets where coming in blocks with headers and check sum data, and needed to be calculated and parsed.

Headache is gone :wall: , feel pretty good now. :rolleyes:

...nothing we'd ever have guessed without seeing all your code :stuck_out_tongue: