Skip to content

Commit

Permalink
fixed bug in ImageTranscoder that would cause failure due to file nam…
Browse files Browse the repository at this point in the history
…e collision whenever transcoding jxr to jxr, plus other small fixes
  • Loading branch information
faburaya committed Jun 7, 2017
1 parent cfe1271 commit f651b84
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 37 deletions.
9 changes: 7 additions & 2 deletions ImageTranscoder/MetadataCopier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,11 @@ namespace application
WWAPI::RaiseHResultException(hr, strConv.to_bytes(woss.str()).c_str(), "IWICMetadataQueryReader::GetMetadataByName");
}

/* If the item is in fact a group of sub-items, then it cannot be copied like this.
Instead, such group would have to be explicitly listed in MetadataCopyMap.xml. */
if (propVar.vt == VT_UNKNOWN)
continue;

hr = embQueryWriter->SetMetadataByName(query, &propVar);
if (FAILED(hr))
{
Expand Down Expand Up @@ -919,7 +924,7 @@ namespace application
_propvariant_t writerPropVar;
writerPropVar.vt = VT_UNKNOWN;
writerPropVar.punkVal = embQueryWriter.Get();
writerPropVar.punkVal->AddRef();
//writerPropVar.punkVal->AddRef();

hr = to->SetMetadataByName(UnwrapCString(entry.toPath), &writerPropVar);
if (FAILED(hr))
Expand All @@ -932,7 +937,7 @@ namespace application
strConv.to_bytes(woss.str()).c_str(),
"IWICMetadataQueryWriter::SetMetadataByName");
}

});// for_each loop end
}

Expand Down
57 changes: 33 additions & 24 deletions ImageTranscoder/MetadataCopyMap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@
<entry guid="{19e4a5aa-5662-4fc5-a0c0-1758028e1057}" name="jpeg"/>
</container>
<metadata>
<entry guid="{79007028-268D-45D6-A3C2-354E6A504BC9}" name="App0"/>
<entry guid="{8FD3DFC3-F951-492B-817F-69C2E6D9A5B0}" name="App1"/>
<entry guid="{326556A2-F502-4354-9CC0-8E3F48EAF6B5}" name="App13"/>
<entry guid="{537396C6-2D8A-4BB6-9BF8-2F0A8E2A3ADF}" name="IFD"/>
<entry guid="{BB5ACC38-F216-4CEC-A6C5-5F6E739763A9}" name="XMP"/>
<entry guid="{1C3C4F9D-B84A-467D-9493-36CFBD59EA57}" name="EXIF"/>
<entry guid="{7134AB8A-9351-44AD-AF62-448DB6B502EC}" name="GPS"/>
<entry guid="{BB5ACC38-F216-4CEC-A6C5-5F6E739763A9}" name="XMP"/>
<entry guid="{16100D66-8570-4BB9-B92D-FDA4B23ECE67}" name="IRB"/>
<entry guid="{4FAB0914-E129-4087-A1D1-BC812D45A7B5}" name="IPTC"/>
<entry guid="{0010568C-0852-4E6A-B191-5C33AC5B0430}" name="8BIMIPTC"/>
</metadata>
</formats>

Expand All @@ -26,45 +32,64 @@
<map>
<case srcFormat="tiff" destFormat="jpeg">
<entry metaFormat="IFD" fromPath="/ifd" toPath="/app1/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/ifd/exif" toPath="/app1/ifd/exif" onlyCommon="true"/>
<entry metaFormat="GPS" fromPath="/ifd/gps" toPath="/app1/ifd/exif" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/ifd/irb/8bimiptc/iptc" toPath="/app13/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
<case srcFormat="jpeg" destFormat="tiff">
<entry metaFormat="IFD" fromPath="/app1/ifd" toPath="/ifd" onlyCommon="true"/>
<entry metaFormat="IFD" fromPath="/app1" toPath="/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/xmp" toPath="/ifd/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/xmp" toPath="/ifd/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/app1/ifd/exif" toPath="/ifd/exif" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/app13/irb/8bimiptc/iptc" toPath="/ifd/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
<case srcFormat="jpegxr" destFormat="jpeg">
<entry metaFormat="IFD" fromPath="/ifd" toPath="/app1/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/ifd/exif" toPath="/app1/ifd/exif" onlyCommon="true"/>
<entry metaFormat="GPS" fromPath="/ifd/gps" toPath="/app1/ifd/exif" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/ifd/irb/8bimiptc/iptc" toPath="/app13/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
<case srcFormat="jpeg" destFormat="jpegxr">
<entry metaFormat="IFD" fromPath="/app1/ifd" toPath="/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/xmp" toPath="/ifd/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/xmp" toPath="/ifd/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/app1/ifd/exif" toPath="/ifd/exif" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/app13/irb/8bimiptc/iptc" toPath="/ifd/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
<case srcFormat="tiff" destFormat="jpegxr">
<entry metaFormat="IFD" fromPath="/ifd" toPath="/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/ifd/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/ifd/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/ifd/exif" toPath="/ifd/exif" onlyCommon="true"/>
<entry metaFormat="GPS" fromPath="/ifd/gps" toPath="/ifd/gps" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/ifd/irb/8bimiptc/iptc" toPath="/ifd/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
<case srcFormat="jpegxr" destFormat="tiff">
<entry metaFormat="IFD" fromPath="/ifd" toPath="/ifd" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/ifd/xmp" onlyCommon="true"/>
<entry metaFormat="XMP" fromPath="/ifd/xmp" toPath="/ifd/xmp" onlyCommon="false"/>
<entry metaFormat="EXIF" fromPath="/ifd/exif" toPath="/ifd/exif" onlyCommon="true"/>
<entry metaFormat="GPS" fromPath="/ifd/gps" toPath="/ifd/gps" onlyCommon="true"/>
<entry metaFormat="IPTC" fromPath="/ifd/irb/8bimiptc/iptc" toPath="/ifd/irb/8bimiptc/iptc" onlyCommon="false"/>
</case>
</map>

<!-- The items that are common to several container formats -->
<items>
<entry id="0" metaFormat="GPS" rational="false" name="GPSVersionID"/>
<entry id="1" metaFormat="GPS" rational="false" name="GPSLatitudeRef"/>
<entry id="2" metaFormat="GPS" rational="true" name="GPSLatitude"/>
<entry id="3" metaFormat="GPS" rational="false" name="GPSLongitudeRef"/>
<entry id="4" metaFormat="GPS" rational="true" name="GPSLongitude"/>
<entry id="5" metaFormat="GPS" rational="false" name="GPSAltitudeRef"/>
<entry id="6" metaFormat="GPS" rational="true" name="GPSAltitude"/>
<entry id="7" metaFormat="GPS" rational="true" name="GPSTimeStamp"/>
<entry id="8" metaFormat="GPS" rational="false" name="GPSSatellites"/>
<entry id="9" metaFormat="GPS" rational="false" name="GPSStatus"/>
<entry id="10" metaFormat="GPS" rational="false" name="GPSMeasureMode"/>
<entry id="11" metaFormat="GPS" rational="true" name="GPSDOP"/>
<entry id="12" metaFormat="GPS" rational="false" name="GPSSpeedRef"/>
<entry id="13" metaFormat="GPS" rational="true" name="GPSSpeed"/>
<entry id="14" metaFormat="GPS" rational="false" name="GPSTrackRef"/>
<entry id="15" metaFormat="GPS" rational="true" name="GPSTrack"/>
<entry id="256" metaFormat="IFD" rational="false" name="ImageWidth"/>
<entry id="257" metaFormat="IFD" rational="false" name="ImageLength"/>
<entry id="258" metaFormat="IFD" rational="false" name="BitsPerSample"/>
Expand Down Expand Up @@ -152,21 +177,5 @@
<entry id="41994" metaFormat="EXIF" rational="false" name="Sharpness"/>
<entry id="41995" metaFormat="EXIF" rational="false" name="DeviceSettingDescription"/>
<entry id="41996" metaFormat="EXIF" rational="false" name="SubjectDistanceRange"/>
<entry id="0" metaFormat="EXIF" rational="false" name="GPSVersionID"/>
<entry id="1" metaFormat="EXIF" rational="false" name="GPSLatitudeRef"/>
<entry id="2" metaFormat="EXIF" rational="true" name="GPSLatitude"/>
<entry id="3" metaFormat="EXIF" rational="false" name="GPSLongitudeRef"/>
<entry id="4" metaFormat="EXIF" rational="true" name="GPSLongitude"/>
<entry id="5" metaFormat="EXIF" rational="false" name="GPSAltitudeRef"/>
<entry id="6" metaFormat="EXIF" rational="true" name="GPSAltitude"/>
<entry id="7" metaFormat="EXIF" rational="true" name="GPSTimeStamp"/>
<entry id="8" metaFormat="EXIF" rational="false" name="GPSSatellites"/>
<entry id="9" metaFormat="EXIF" rational="false" name="GPSStatus"/>
<entry id="10" metaFormat="EXIF" rational="false" name="GPSMeasureMode"/>
<entry id="11" metaFormat="EXIF" rational="true" name="GPSDOP"/>
<entry id="12" metaFormat="EXIF" rational="false" name="GPSSpeedRef"/>
<entry id="13" metaFormat="EXIF" rational="true" name="GPSSpeed"/>
<entry id="14" metaFormat="EXIF" rational="false" name="GPSTrackRef"/>
<entry id="15" metaFormat="EXIF" rational="true" name="GPSTrack"/>
</items>
</metadata>
24 changes: 13 additions & 11 deletions ImageTranscoder/WicJpegTranscoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ namespace application
std::wstring GenerateOutputFileName(const std::wstring &inputFileName, bool isJXR)
{
return std::wstring(inputFileName.begin(),
inputFileName.begin() + inputFileName.find_last_of(L'.'))
+ (isJXR ? L".jxr" : L"_R.jpg");
inputFileName.begin() + inputFileName.find_last_of(L'.')
) + (isJXR ? L"_R.jxr" : L"_R.jpg");
}


Expand Down Expand Up @@ -109,15 +109,15 @@ namespace application
void CopyMetadata(IntfType1 *source, IntfType2 *dest, bool sameFormat)
{
HRESULT hr;

// When formats are the same, metadata can be copied directly:
if (sameFormat)
{
ComPtr<IWICMetadataBlockReader> metadataBlockReader;
hr = source->QueryInterface(IID_PPV_ARGS(metadataBlockReader.GetAddressOf()));

/* when the source interface is an encoder object, if the image format does not support container
level metadata, this operation is expected to fail and the function should quit at this point */
// when the source interface is an encoder object, if the image format does not support container
// level metadata, this operation is expected to fail and the function should quit at this point
if (hr == E_NOINTERFACE)
return;

Expand Down Expand Up @@ -290,6 +290,7 @@ namespace application

/// <summary>
/// Transcodes the specified image file from any format supported by Windows to JPEG.
/// This version of implementation is meant for classical desktop apps.
/// </summary>
/// <param name="filePath">Full name of the file.</param>
/// <param name="toJXR">if set to <c>true</c>, reencodes to JPEG XR.</param>
Expand All @@ -301,7 +302,7 @@ namespace application
try
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> strConv;
const auto wcsFilePath = strConv.from_bytes(filePath);
auto wcsFilePath = strConv.from_bytes(filePath);

// Create decoder from input image file:

Expand All @@ -322,8 +323,8 @@ namespace application
if (FAILED(hr))
WWAPI::RaiseHResultException(hr, "Failed to create file stream", "IWICImagingFactory::CreateStream");

auto wcsFileOutName = GenerateOutputFileName(wcsFilePath.c_str(), toJXR);
hr = fileOutStream->InitializeFromFilename(wcsFileOutName.c_str(), GENERIC_WRITE);
auto outFileName = GenerateOutputFileName(wcsFilePath.c_str(), toJXR);
hr = fileOutStream->InitializeFromFilename(outFileName.c_str(), GENERIC_WRITE);
if (FAILED(hr))
WWAPI::RaiseHResultException(hr, "Failed to initialize output file stream", "IWICStream::InitializeFromFilename");

Expand Down Expand Up @@ -356,6 +357,7 @@ namespace application

/// <summary>
/// Transcodes the specified image file from any format supported by Windows to JPEG.
/// This version of implementation is meant for WinRT.
/// </summary>
/// <param name="inputStream">The stream for the input image file.</param>
/// <param name="outputStream">The stream for the output image file.</param>
Expand All @@ -370,9 +372,9 @@ namespace application
HRESULT hr;
ComPtr<IWICBitmapDecoder> decoder;
hr = m_wicImagingFactory->CreateDecoderFromStream(inputStream,
nullptr,
WICDecodeMetadataCacheOnLoad,
decoder.GetAddressOf());
nullptr,
WICDecodeMetadataCacheOnLoad,
decoder.GetAddressOf());
if (FAILED(hr))
WWAPI::RaiseHResultException(hr, "Failed to create image decoder", "IWICImagingFactory::CreateDecoderFromStream");

Expand Down

0 comments on commit f651b84

Please sign in to comment.