I'm having trouble when try to attach original exif data back to image after rotating it by GD image.
How I rotate image
rotatedImage = gdImageRotateInterpolated(image, (360-rotationDeg)%360, 0);
imgBuffer = (unsigned char *)gdImageJpegPtr(rotatedImage, &imgSize, 85);
Then I have a function try to write extracted exif data from original image to rotated one by combine image buffer with exif buffer but I can't still see Exif data while inspecting the image. I'm using libexif
writeExifData(unsigned char* &imageBuffer, int &size, ExifData* exifData) {
if (!exifData) {
return;
}
TRACE("Image Size: %d", size);
// save exif data into buffer
unsigned char* buf = NULL;
unsigned int bufSize = 0;
exif_data_save_data(exifData, &buf, &bufSize);
std::vector<unsigned char> combinedBuffer(size + bufSize);
// Copy the image buffer
std::copy(imageBuffer, imageBuffer + size, combinedBuffer.begin());
// Copy the EXIF buffer
std::copy(buf, buf + bufSize, combinedBuffer.begin() + size);
unsigned char* newImageBuffer = (unsigned char*)malloc(combinedBuffer.size());
memcpy(newImageBuffer, combinedBuffer.data(), combinedBuffer.size());
imageBuffer = newImageBuffer;
size = combinedBuffer.size();
}
Any other way that I can have new image buffer include all Exif data from original image?
The JPEG image format consists of a number of segments using tag-length-value encoding. Furthermore, APP1 data for EXIF is supposed to come right after the SOI marker in the file, which is the first two bytes of your JPEG.
exif_save_dataproduces the "value" part but you need to wrap that in a segment yourself.Thus, you can do the following:
If you do not have access to
htobe16you can usehtonsas well.