This is how I implemented this using js. The marker you are looking for is the Sofn marker and the pseudocode would basically be:
- start from the first byte
- the beginning of a segment will always be FFfollowed by another byte indicating marker type (those 2 bytes are called the marker)
- if that other byte is 01orD1throughD9, there is no data in that segment, so proceed to next segment
- if that marker is C0orC2(or any other Cn, more detail in the comments of the code), thats the Sofn marker you're looking for
- the following bytes after the marker will be P (1 byte), L (2 bytes), Height (2 bytes), Width (2 bytes) respectively
 
- otherwise, the next two bytes followed by it will be the length property (length of entire segment excluding the marker, 2 bytes), use that to skip to the next segment
- repeat until you find the Sofn marker
function getJpgSize(hexArr) {
  let i = 0;
  let marker = '';
  while (i < hexArr.length) {
    //ff always start a marker,
    //something's really wrong if the first btye isn't ff
    if (hexArr[i] !== 'ff') {
      console.log(i);
      throw new Error('aaaaaaa');
    }
    //get the second byte of the marker, which indicates the marker type
    marker = hexArr[++i];
    //these are segments that don't have any data stored in it, thus only 2 bytes
    //01 and D1 through D9
    if (marker === '01' || (!isNaN(parseInt(marker[1])) && marker[0] === 'd')) {
      i++;
      continue;
    }
    /*
    sofn marker: https://www.w3.org/Graphics/JPEG/itu-t81.pdf pg 36
      INFORMATION TECHNOLOGY –
      DIGITAL COMPRESSION AND CODING
      OF CONTINUOUS-TONE STILL IMAGES –
      REQUIREMENTS AND GUIDELINES
    basically, sofn (start of frame, type n) segment contains information
    about the characteristics of the jpg
    the marker is followed by:
      - Lf [frame header length], two bytes
      - P [sample precision], one byte
      - Y [number of lines in the src img], two bytes, which is essentially the height
      - X [number of samples per line], two bytes, which is essentially the width 
      ... [other parameters]
    sofn marker codes: https://www.digicamsoft.com/itu/itu-t81-36.html
    apparently there are other sofn markers but these two the most common ones
    */
    if (marker === 'c0' || marker === 'c2') {
      break;
    }
    //2 bytes specifying length of the segment (length excludes marker)
    //jumps to the next seg
    i += parseInt(hexArr.slice(i + 1, i + 3).join(''), 16) + 1;
  }
  const size = {
    height: parseInt(hexArr.slice(i + 4, i + 6).join(''), 16),
    width: parseInt(hexArr.slice(i + 6, i + 8).join(''), 16),
  };
  return size;
}