#pragma once #include #include // Turns a picked image into a file the gallery's upload API accepts. // // Three things must be true of the result: no EXIF (the gallery publishes the // uploaded file verbatim as its full-size download, so embedded GPS would be // public), a .jpg or .png extension (server.go rejects anything else, HEIC // included), and under nginx's 20M body cap. // // JPEG and PNG take a lossless route — whole metadata segments are dropped // without touching the compressed image data — so the published file keeps the // original sensor pixels. Anything else, or a file whose EXIF orientation must // be baked in, is decoded and re-encoded as JPEG (HEIC via Qt's qtimageformats // plugin). The strippers are a direct port of the Android app's. class ImagePrep { public: struct Prepared { QString filePath; QString note; // non-empty when the app departed from a byte-exact copy QString error; bool ok() const { return error.isEmpty(); } }; // Writes the upload-ready file into cacheDir as baseName.(jpg|png). static Prepared prepare(const QString &sourcePath, const QString &cacheDir, const QString &baseName); private: static QByteArray stripJpegSegments(const QByteArray &src); // empty on parse failure static QByteArray stripPngChunks(const QByteArray &src); static bool isJpeg(const QByteArray &b); static bool isPng(const QByteArray &b); };