From source code:
uint16_t cropPosX; /* specifies from which sensor row/col the video frame was copied (8x2 blocks) */
uint16_t cropPosY; /* (can be used to process dead/hot pixels) */
Why 8x2?
- when copying raw data, you can only do so starting from a multiple of 8 pixels (14 bytes). Why? see the definition of struct raw_pixblock.
- to keep things simple, all the code in ML assumes a Bayer order of RG;GB, so you should always skip an even number of lines
Therefore, for focus pixel correction, you are interested in these two offsets.
uint16_t panPosX; /* specifies the panning offset which is cropPos, but with higher resolution (1x1 blocks) */
uint16_t panPosY; /* (it's the frame area from sensor the user wants to see) */
These were meant to be used for digital dolly at pixel-level resolution; however, I don't remember this feature being actually implemented. You do not need them - in theory (there is a bug, see below).
Now, cropPosX/Y are actually skip_x/y rounded to multiples of 8:
hdr->cropPosX = (skip_x + 7) & ~7; /* same as (skip_x + 7) / 8 * 8, using integer math */
hdr->cropPosY = (skip_y + 7) & ~7;
hdr->panPosX = skip_x;
hdr->panPosY = skip_y;
How are those skip offsets used when copying the raw buffer?
edmac_copy_rectangle_cbr_start(ptr, raw_info.buffer, raw_info.pitch, (skip_x+7)/8*14, skip_y/2*2, res_x*14/8, 0, 0, res_x*14/8, res_y, &mlv_rec_dma_cbr_r, &mlv_rec_dma_cbr_w, NULL);
So, clearly they are pixels, not bytes, and they are the top-left corner of the image.
Notice cropPosY does not respect the specification. It should be: hdr->cropPosY = skip_y & ~1. That's a bug.
To work around for existing MLV files, assume cropPosY = panPosY & ~1. That should do the trick.
So maybe the raw buffer is actually:
(active_area.x2 + active_area.x1) x (active_area.y2 + active_area.y1)
Sorry, this is nonsense. Raw buffer size is raw_info.width x height. Active area is the part that contains useful image data. What's outside active area is optical black area. Pitch is width in bytes.
To get the entire raw buffer from a DNG, including OB area: dcraw -4 -E
To get the active area only: dcraw -4 -D
Hope this helps.