1

So I'm reading JPG files, and I've finished reading the 'header' data and now I'm onto the actual image data. Thing is, I don't know the size of the image beforehand, so I cannot create an array to read from. What I could do, though, is read from the end of the 'header' until the end of the image (two bytes: FF and D9), ByteArrayOutputStream to hold each value as it is read, until I encounter byte D9 after byte FF. How would I go about doing this?

My code so far, including JPG recognition just so you know the context:

// check header data, assign header data to important fields

    // Start Of Image (SOI) must be FFD8 and the next marker must be FF
    if(!(bData[0] == (byte) 0xFF && bData[1] == (byte) 0xD8
            && this.bData[2] == (byte) 0xFF))
        this.isValid = false;

    // check if file is not valid
    if(!isValid) {
        System.err.printf("ERROR: File %s is not"
                        + " registered as a bitmap!\n", filename);
        Logger.getLogger(Bitmap.class.getName()).log(Level.SEVERE, null, new IllegalArgumentException());
    }

    // If the next values are correct, then the data stream starts at SOI
    // If not, the data stream is raw
    this.isRawDataStream = !(bData[3] == (byte) 0xE0
            && bData[6]  == (byte) 0x4A
            && bData[7]  == (byte) 0x46
            && bData[8]  == (byte) 0x49
            && bData[9]  == (byte) 0x46
            && bData[10] == (byte) 0x00);

    // get size of image
    ByteArrayOutputStream iData = new ByteArrayOutputStream();

    // start at index 20 of the file (end of 'header')
    // read until End of Image
    /* while(!(iData at i is FF and iData at i+1 is D9)) {
        ???
    }
    */

edit I'm doing this as an exercise to better understand file formats among other things, and I may be horribly misinterpreting JFIF. If I am, don't hesitate to tell me.

Tetramputechture
  • 2,911
  • 2
  • 33
  • 48
  • 1
    I'd recommend using a `ByteArrayOutputStream` or `ByteBuffer` or similar. `ArrayList` will have a large memory footprint from boxing every `byte` as a `Byte` object. – John Kugelman Oct 09 '14 at 00:23
  • Also `byteData[0].equals("FF")` should be `byteData[0] == (byte) 0xFF`, assuming `byteData` is a `byte[]` array. Comparing `byte`s against `String`s won't work. – John Kugelman Oct 09 '14 at 00:25
  • 1
    It would be best to switch to a `byte[]` array, then. Using `String`s would be an unnecessary inefficiency. – John Kugelman Oct 09 '14 at 00:28
  • I didn't realize you could convert hex values to bytes, thank you! That even makes my Bitmap class more efficient, too! (: @JohnKugelman – Tetramputechture Oct 09 '14 at 00:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62712/discussion-between-tetramputechture-and-john-kugelman). – Tetramputechture Oct 09 '14 at 00:43

1 Answers1

0

The size of the image is in the SOF (Start of Frame) marker.

In rereading, I think the original poster is mistaken about the structure of a JPEG stream.

It must begin with a SOI market and end with an EOI marker. Beyond that, markers can vary in ordering.

There are some other restrictions: The SOF marker must come before the SOS markers. The DHT and DQT markers must appear before any SOS markers that use them.

On top of that, there are various JPEG file formats that require an APPn marker at the start of the stream.

The code above and question do not reflect the variable nature of a JPEG stream.

user3344003
  • 20,574
  • 3
  • 26
  • 62