The handover photos only showed half the car
Every photo a driver took at a handover reached the office as its top-left corner. Half to nine-tenths of each frame was lost, and none of it can be recovered.
You run a self-drive car rental business in Goa. At every pickup and every return your driver photographs the car, panel by panel, because when a customer disputes a damage charge those photographs are the whole argument. One morning the office opens a booking and each picture is a corner of a car: a bonnet, the edge of a wing, then the edge of the frame. The rest never arrived.
It was not one booking. Every handover photo since the release before last had come in the same way, and how much was missing depended on the phone. Between half and nearly nine-tenths of each frame was gone, and the better the camera, the worse the loss: a phone with a 108-megapixel sensor was sending about one-sixtieth of what the driver had seen on his screen. There was nothing to go back for, either. The full picture never left the phone, so the evidence for every dispute in that window is gone for good.
What was actually going on
Two days before this report we had looked at a “cropped thumbnail” complaint on the same app and concluded the stored photos were fine and only the small preview tile in the app was cut off. That answer was wrong, and it is worth saying so, because the way it was wrong is the whole story. The stored files looked like whole photographs. They had the right proportions and a plausible size. Nothing about them said “a quarter of a car” until somebody laid them over the originals and measured: the uploaded file matched the top-left half of the original in each direction, corner to corner, with a correlation of 0.9998. They were not squashed. They were cut.
The cause, in plain words: before sending a photo, the app shrinks it. To do that it asks the phone how big the photo is, and on this kind of phone the answer is the size of a smaller working copy the phone keeps for large images, not the size of the photograph. For a 4,000 by 3,000 frame the phone said 2,000 by 1,500. The app then told the shrinking routine to keep a box that big from the top-left corner, and that routine, it turned out, always cuts a box first and scales second. So it cut half the photo in each direction and enlarged it back up.
Small photos were never affected, because the phone does not keep a reduced copy of a small image. That is why the fault looked intermittent, and why an earlier test with small images passed. Every real camera frame is large. A previous attempt at the same complaint had adjusted the arithmetic for the photo’s proportions, which was never the cause; with the right dimensions that path loses a tenth of a percent.
What we changed
The first fix read the true pixel size from the file itself and planned a box that provably covered the whole frame. It worked, on a real driver’s phone, across 20 test images and then five more at 64, 108 and 200 megapixels. Then we threw it away. It depended on a hand-written copy of the library’s private behaviour, which a future update could silently drift from with no test able to notice, and when its own file-reading failed it fell back to asking the phone, which was the broken thing. A fix that is correct today and a trap tomorrow is not a fix.
The replacement uses a different library chosen after reading its source rather than its description. It takes the size from the decoded picture itself, so no number the app supplies can disagree with reality, and it only scales; there is no cutting step anywhere in its path. One test asserts the scaling mode, because switching it is a one-word edit that would crop again. Verified on the driver’s phone with 38 images from 200 by 150 pixels up to 200 megapixels, every proportion and orientation the camera produces, and the twelve real photographs from the driver’s own session, each one whole after the round trip to storage. Shipped as app version 1.0.8.
What it did not fix
The photos already uploaded stay as they are. The full frame was discarded on the phone before anything was sent, so no server-side work can bring them back.
The app cannot update itself, so drivers kept sending cut photos until the new version was installed. We only learned the fault was live at all because a handover note said the previous release had not been uploaded to the store, and the owner corrected it: it had been, which meant every driver was on it.
Two smaller things were found and left. A very small 200 by 150 upload arrives whole, but the burned-in watermark covers its top third. And the home-screen badge saying bookings still need photos only clears when the driver opens the pending screen, so a fully uploaded booking keeps nagging.
The mechanism, briefly
The native resize call was a crop-and-resize with no resize-only mode, fed a crop rectangle built from a decoder’s power-of-two downsampled size rather than the file’s pixel size. It was replaced with a contain-mode scale that reads the decoded bitmap’s own dimensions, with a test pinning the mode and a byte-target loop that re-derives from the original each pass instead of resampling its own output.
Where this ends up
A damage dispute is decided by what the photograph shows, which is why the handover capture in Sazinga Rentals is verified frame by frame against the original on a real phone, not judged by whether the upload looks like a photo.