1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2008-2012 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // $Id: DownsamplePicture.cpp 140 2012-11-11 21:41:31Z roman $ |
---|
6 | |
---|
7 | #include "stdafx.h" |
---|
8 | #include <atlimage.h> |
---|
9 | //#include "resource.h" |
---|
10 | #include "rofiles.h" |
---|
11 | |
---|
12 | /////////////////////////////////////////////////////////// |
---|
13 | // CModule |
---|
14 | |
---|
15 | class CModule : |
---|
16 | public CAtlExeModuleT<CModule>//, |
---|
17 | //public CWtlExeModuleT<CModule> |
---|
18 | { |
---|
19 | public: |
---|
20 | |
---|
21 | //////////////////////////////////////////////////////// |
---|
22 | // CGdiPlusInitialization |
---|
23 | |
---|
24 | class CGdiPlusInitialization |
---|
25 | { |
---|
26 | private: |
---|
27 | ULONG_PTR m_nToken; |
---|
28 | |
---|
29 | public: |
---|
30 | // CGdiPlusInitialization |
---|
31 | CGdiPlusInitialization() : |
---|
32 | m_nToken(0) |
---|
33 | { |
---|
34 | Gdiplus::GdiplusStartupInput Input; |
---|
35 | Gdiplus::GdiplusStartupOutput Output; |
---|
36 | __D(Gdiplus::GdiplusStartup(&m_nToken, &Input, &Output) == Gdiplus::Ok, E_UNNAMED); |
---|
37 | _A(m_nToken); |
---|
38 | } |
---|
39 | ~CGdiPlusInitialization() |
---|
40 | { |
---|
41 | if(m_nToken) |
---|
42 | { |
---|
43 | Gdiplus::GdiplusShutdown(m_nToken); |
---|
44 | m_nToken = 0; |
---|
45 | } |
---|
46 | } |
---|
47 | }; |
---|
48 | |
---|
49 | private: |
---|
50 | CPath m_sSourcePath; |
---|
51 | CPath m_sDestinationPath; |
---|
52 | |
---|
53 | public: |
---|
54 | // CModule |
---|
55 | CModule() throw() |
---|
56 | { |
---|
57 | AtlTraceSetDefaultSettings(); |
---|
58 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
59 | _W(CExceptionFilter::Initialize()); |
---|
60 | } |
---|
61 | ~CModule() throw() |
---|
62 | { |
---|
63 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
64 | CExceptionFilter::Terminate(); |
---|
65 | } |
---|
66 | const CPath& GetSourcePath() const |
---|
67 | { |
---|
68 | return m_sSourcePath; |
---|
69 | } |
---|
70 | VOID SetSourcePath(LPCTSTR pszSourcePath) |
---|
71 | { |
---|
72 | m_sSourcePath = pszSourcePath; |
---|
73 | } |
---|
74 | const CPath& GetDestinationPath() const |
---|
75 | { |
---|
76 | return m_sDestinationPath; |
---|
77 | } |
---|
78 | VOID SetDestinationPath(LPCTSTR pszDestinationPath) |
---|
79 | { |
---|
80 | m_sDestinationPath = pszDestinationPath; |
---|
81 | } |
---|
82 | static LPCSTR StringFromPropertyTag(UINT nPropertyTag) |
---|
83 | { |
---|
84 | static const struct { UINT nPropertyTag; LPCSTR pszName; } g_pMap[] = |
---|
85 | { |
---|
86 | #define A(x) { x, #x }, |
---|
87 | A(PropertyTagTypeByte) |
---|
88 | A(PropertyTagTypeASCII) |
---|
89 | A(PropertyTagTypeShort) |
---|
90 | A(PropertyTagTypeLong) |
---|
91 | A(PropertyTagTypeRational) |
---|
92 | A(PropertyTagTypeUndefined) |
---|
93 | A(PropertyTagTypeSLONG) |
---|
94 | A(PropertyTagTypeSRational) |
---|
95 | A(PropertyTagExifIFD) |
---|
96 | A(PropertyTagGpsIFD) |
---|
97 | A(PropertyTagNewSubfileType) |
---|
98 | A(PropertyTagSubfileType) |
---|
99 | A(PropertyTagImageWidth) |
---|
100 | A(PropertyTagImageHeight) |
---|
101 | A(PropertyTagBitsPerSample) |
---|
102 | A(PropertyTagCompression) |
---|
103 | A(PropertyTagPhotometricInterp) |
---|
104 | A(PropertyTagThreshHolding) |
---|
105 | A(PropertyTagCellWidth) |
---|
106 | A(PropertyTagCellHeight) |
---|
107 | A(PropertyTagFillOrder) |
---|
108 | A(PropertyTagDocumentName) |
---|
109 | A(PropertyTagImageDescription) |
---|
110 | A(PropertyTagEquipMake) |
---|
111 | A(PropertyTagEquipModel) |
---|
112 | A(PropertyTagStripOffsets) |
---|
113 | A(PropertyTagOrientation) |
---|
114 | A(PropertyTagSamplesPerPixel) |
---|
115 | A(PropertyTagRowsPerStrip) |
---|
116 | A(PropertyTagStripBytesCount) |
---|
117 | A(PropertyTagMinSampleValue) |
---|
118 | A(PropertyTagMaxSampleValue) |
---|
119 | A(PropertyTagXResolution) |
---|
120 | A(PropertyTagYResolution) |
---|
121 | A(PropertyTagPlanarConfig) |
---|
122 | A(PropertyTagPageName) |
---|
123 | A(PropertyTagXPosition) |
---|
124 | A(PropertyTagYPosition) |
---|
125 | A(PropertyTagFreeOffset) |
---|
126 | A(PropertyTagFreeByteCounts) |
---|
127 | A(PropertyTagGrayResponseUnit) |
---|
128 | A(PropertyTagGrayResponseCurve) |
---|
129 | A(PropertyTagT4Option) |
---|
130 | A(PropertyTagT6Option) |
---|
131 | A(PropertyTagResolutionUnit) |
---|
132 | A(PropertyTagPageNumber) |
---|
133 | A(PropertyTagTransferFuncition) |
---|
134 | A(PropertyTagSoftwareUsed) |
---|
135 | A(PropertyTagDateTime) |
---|
136 | A(PropertyTagArtist) |
---|
137 | A(PropertyTagHostComputer) |
---|
138 | A(PropertyTagPredictor) |
---|
139 | A(PropertyTagWhitePoint) |
---|
140 | A(PropertyTagPrimaryChromaticities) |
---|
141 | A(PropertyTagColorMap) |
---|
142 | A(PropertyTagHalftoneHints) |
---|
143 | A(PropertyTagTileWidth) |
---|
144 | A(PropertyTagTileLength) |
---|
145 | A(PropertyTagTileOffset) |
---|
146 | A(PropertyTagTileByteCounts) |
---|
147 | A(PropertyTagInkSet) |
---|
148 | A(PropertyTagInkNames) |
---|
149 | A(PropertyTagNumberOfInks) |
---|
150 | A(PropertyTagDotRange) |
---|
151 | A(PropertyTagTargetPrinter) |
---|
152 | A(PropertyTagExtraSamples) |
---|
153 | A(PropertyTagSampleFormat) |
---|
154 | A(PropertyTagSMinSampleValue) |
---|
155 | A(PropertyTagSMaxSampleValue) |
---|
156 | A(PropertyTagTransferRange) |
---|
157 | A(PropertyTagJPEGProc) |
---|
158 | A(PropertyTagJPEGInterFormat) |
---|
159 | A(PropertyTagJPEGInterLength) |
---|
160 | A(PropertyTagJPEGRestartInterval) |
---|
161 | A(PropertyTagJPEGLosslessPredictors) |
---|
162 | A(PropertyTagJPEGPointTransforms) |
---|
163 | A(PropertyTagJPEGQTables) |
---|
164 | A(PropertyTagJPEGDCTables) |
---|
165 | A(PropertyTagJPEGACTables) |
---|
166 | A(PropertyTagYCbCrCoefficients) |
---|
167 | A(PropertyTagYCbCrSubsampling) |
---|
168 | A(PropertyTagYCbCrPositioning) |
---|
169 | A(PropertyTagREFBlackWhite) |
---|
170 | A(PropertyTagICCProfile) |
---|
171 | A(PropertyTagGamma) |
---|
172 | A(PropertyTagICCProfileDescriptor) |
---|
173 | A(PropertyTagSRGBRenderingIntent) |
---|
174 | A(PropertyTagImageTitle) |
---|
175 | A(PropertyTagCopyright) |
---|
176 | A(PropertyTagResolutionXUnit) |
---|
177 | A(PropertyTagResolutionYUnit) |
---|
178 | A(PropertyTagResolutionXLengthUnit) |
---|
179 | A(PropertyTagResolutionYLengthUnit) |
---|
180 | A(PropertyTagPrintFlags) |
---|
181 | A(PropertyTagPrintFlagsVersion) |
---|
182 | A(PropertyTagPrintFlagsCrop) |
---|
183 | A(PropertyTagPrintFlagsBleedWidth) |
---|
184 | A(PropertyTagPrintFlagsBleedWidthScale) |
---|
185 | A(PropertyTagHalftoneLPI) |
---|
186 | A(PropertyTagHalftoneLPIUnit) |
---|
187 | A(PropertyTagHalftoneDegree) |
---|
188 | A(PropertyTagHalftoneShape) |
---|
189 | A(PropertyTagHalftoneMisc) |
---|
190 | A(PropertyTagHalftoneScreen) |
---|
191 | A(PropertyTagJPEGQuality) |
---|
192 | A(PropertyTagGridSize) |
---|
193 | A(PropertyTagThumbnailFormat) |
---|
194 | A(PropertyTagThumbnailWidth) |
---|
195 | A(PropertyTagThumbnailHeight) |
---|
196 | A(PropertyTagThumbnailColorDepth) |
---|
197 | A(PropertyTagThumbnailPlanes) |
---|
198 | A(PropertyTagThumbnailRawBytes) |
---|
199 | A(PropertyTagThumbnailSize) |
---|
200 | A(PropertyTagThumbnailCompressedSize) |
---|
201 | A(PropertyTagColorTransferFunction) |
---|
202 | A(PropertyTagThumbnailData) |
---|
203 | A(PropertyTagThumbnailImageWidth) |
---|
204 | A(PropertyTagThumbnailImageHeight) |
---|
205 | A(PropertyTagThumbnailBitsPerSample) |
---|
206 | A(PropertyTagThumbnailCompression) |
---|
207 | A(PropertyTagThumbnailPhotometricInterp) |
---|
208 | A(PropertyTagThumbnailImageDescription) |
---|
209 | A(PropertyTagThumbnailEquipMake) |
---|
210 | A(PropertyTagThumbnailEquipModel) |
---|
211 | A(PropertyTagThumbnailStripOffsets) |
---|
212 | A(PropertyTagThumbnailOrientation) |
---|
213 | A(PropertyTagThumbnailSamplesPerPixel) |
---|
214 | A(PropertyTagThumbnailRowsPerStrip) |
---|
215 | A(PropertyTagThumbnailStripBytesCount) |
---|
216 | A(PropertyTagThumbnailResolutionX) |
---|
217 | A(PropertyTagThumbnailResolutionY) |
---|
218 | A(PropertyTagThumbnailPlanarConfig) |
---|
219 | A(PropertyTagThumbnailResolutionUnit) |
---|
220 | A(PropertyTagThumbnailTransferFunction) |
---|
221 | A(PropertyTagThumbnailSoftwareUsed) |
---|
222 | A(PropertyTagThumbnailDateTime) |
---|
223 | A(PropertyTagThumbnailArtist) |
---|
224 | A(PropertyTagThumbnailWhitePoint) |
---|
225 | A(PropertyTagThumbnailPrimaryChromaticities) |
---|
226 | A(PropertyTagThumbnailYCbCrCoefficients) |
---|
227 | A(PropertyTagThumbnailYCbCrSubsampling) |
---|
228 | A(PropertyTagThumbnailYCbCrPositioning) |
---|
229 | A(PropertyTagThumbnailRefBlackWhite) |
---|
230 | A(PropertyTagThumbnailCopyRight) |
---|
231 | A(PropertyTagLuminanceTable) |
---|
232 | A(PropertyTagChrominanceTable) |
---|
233 | A(PropertyTagFrameDelay) |
---|
234 | A(PropertyTagLoopCount) |
---|
235 | //A(PropertyTagGlobalPalette) |
---|
236 | //A(PropertyTagIndexBackground) |
---|
237 | //A(PropertyTagIndexTransparent) |
---|
238 | A(PropertyTagPixelUnit) |
---|
239 | A(PropertyTagPixelPerUnitX) |
---|
240 | A(PropertyTagPixelPerUnitY) |
---|
241 | A(PropertyTagPaletteHistogram) |
---|
242 | A(PropertyTagExifExposureTime) |
---|
243 | A(PropertyTagExifFNumber) |
---|
244 | A(PropertyTagExifExposureProg) |
---|
245 | A(PropertyTagExifSpectralSense) |
---|
246 | A(PropertyTagExifISOSpeed) |
---|
247 | A(PropertyTagExifOECF) |
---|
248 | A(PropertyTagExifVer) |
---|
249 | A(PropertyTagExifDTOrig) |
---|
250 | A(PropertyTagExifDTDigitized) |
---|
251 | A(PropertyTagExifCompConfig) |
---|
252 | A(PropertyTagExifCompBPP) |
---|
253 | A(PropertyTagExifShutterSpeed) |
---|
254 | A(PropertyTagExifAperture) |
---|
255 | A(PropertyTagExifBrightness) |
---|
256 | A(PropertyTagExifExposureBias) |
---|
257 | A(PropertyTagExifMaxAperture) |
---|
258 | A(PropertyTagExifSubjectDist) |
---|
259 | A(PropertyTagExifMeteringMode) |
---|
260 | A(PropertyTagExifLightSource) |
---|
261 | A(PropertyTagExifFlash) |
---|
262 | A(PropertyTagExifFocalLength) |
---|
263 | A(PropertyTagExifSubjectArea) |
---|
264 | A(PropertyTagExifMakerNote) |
---|
265 | A(PropertyTagExifUserComment) |
---|
266 | A(PropertyTagExifDTSubsec) |
---|
267 | A(PropertyTagExifDTOrigSS) |
---|
268 | A(PropertyTagExifDTDigSS) |
---|
269 | A(PropertyTagExifFPXVer) |
---|
270 | A(PropertyTagExifColorSpace) |
---|
271 | A(PropertyTagExifPixXDim) |
---|
272 | A(PropertyTagExifPixYDim) |
---|
273 | A(PropertyTagExifRelatedWav) |
---|
274 | A(PropertyTagExifInterop) |
---|
275 | A(PropertyTagExifFlashEnergy) |
---|
276 | A(PropertyTagExifSpatialFR) |
---|
277 | A(PropertyTagExifFocalXRes) |
---|
278 | A(PropertyTagExifFocalYRes) |
---|
279 | A(PropertyTagExifFocalResUnit) |
---|
280 | A(PropertyTagExifSubjectLoc) |
---|
281 | A(PropertyTagExifExposureIndex) |
---|
282 | A(PropertyTagExifSensingMethod) |
---|
283 | A(PropertyTagExifFileSource) |
---|
284 | A(PropertyTagExifSceneType) |
---|
285 | A(PropertyTagExifCfaPattern) |
---|
286 | A(PropertyTagExifCustomRendered) |
---|
287 | A(PropertyTagExifExposureMode) |
---|
288 | A(PropertyTagExifWhiteBalance) |
---|
289 | A(PropertyTagExifDigitalZoomRatio) |
---|
290 | A(PropertyTagExifFocalLengthIn35mmFilm) |
---|
291 | A(PropertyTagExifSceneCaptureType) |
---|
292 | A(PropertyTagExifGainControl) |
---|
293 | A(PropertyTagExifContrast) |
---|
294 | A(PropertyTagExifSaturation) |
---|
295 | A(PropertyTagExifSharpness) |
---|
296 | A(PropertyTagExifDeviceSettingDesc) |
---|
297 | A(PropertyTagExifSubjectDistanceRange) |
---|
298 | A(PropertyTagExifUniqueImageID) |
---|
299 | A(PropertyTagGpsVer) |
---|
300 | A(PropertyTagGpsLatitudeRef) |
---|
301 | A(PropertyTagGpsLatitude) |
---|
302 | A(PropertyTagGpsLongitudeRef) |
---|
303 | A(PropertyTagGpsLongitude) |
---|
304 | A(PropertyTagGpsAltitudeRef) |
---|
305 | A(PropertyTagGpsAltitude) |
---|
306 | A(PropertyTagGpsGpsTime) |
---|
307 | A(PropertyTagGpsGpsSatellites) |
---|
308 | A(PropertyTagGpsGpsStatus) |
---|
309 | A(PropertyTagGpsGpsMeasureMode) |
---|
310 | A(PropertyTagGpsGpsDop) |
---|
311 | A(PropertyTagGpsSpeedRef) |
---|
312 | A(PropertyTagGpsSpeed) |
---|
313 | A(PropertyTagGpsTrackRef) |
---|
314 | A(PropertyTagGpsTrack) |
---|
315 | A(PropertyTagGpsImgDirRef) |
---|
316 | A(PropertyTagGpsImgDir) |
---|
317 | A(PropertyTagGpsMapDatum) |
---|
318 | A(PropertyTagGpsDestLatRef) |
---|
319 | A(PropertyTagGpsDestLat) |
---|
320 | A(PropertyTagGpsDestLongRef) |
---|
321 | A(PropertyTagGpsDestLong) |
---|
322 | A(PropertyTagGpsDestBearRef) |
---|
323 | A(PropertyTagGpsDestBear) |
---|
324 | A(PropertyTagGpsDestDistRef) |
---|
325 | A(PropertyTagGpsDestDist) |
---|
326 | A(PropertyTagGpsProcessingMethod) |
---|
327 | A(PropertyTagGpsAreaInformation) |
---|
328 | A(PropertyTagGpsDate) |
---|
329 | A(PropertyTagGpsDifferential) |
---|
330 | #undef A |
---|
331 | }; |
---|
332 | for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++) |
---|
333 | if(g_pMap[nIndex].nPropertyTag == nPropertyTag) |
---|
334 | return g_pMap[nIndex].pszName; |
---|
335 | return NULL; |
---|
336 | } |
---|
337 | static BOOL FindEncoderClassIdentifier(const WCHAR* pszMimeType, CLSID& ClassIdentifier) |
---|
338 | { |
---|
339 | _A(pszMimeType); |
---|
340 | using namespace Gdiplus; |
---|
341 | UINT nEncoderCount = 0; |
---|
342 | UINT nEncoderDataSize = 0; |
---|
343 | __D(GetImageEncodersSize(&nEncoderCount, &nEncoderDataSize) == Ok, E_UNNAMED); |
---|
344 | CTempBufferT<ImageCodecInfo> pImageCodecInfo; |
---|
345 | __D(pImageCodecInfo.AllocateBytes(nEncoderDataSize), E_OUTOFMEMORY); |
---|
346 | __D(GetImageEncoders(nEncoderCount, nEncoderDataSize, pImageCodecInfo) == Ok, E_UNNAMED); |
---|
347 | for(UINT nEncoderIndex = 0; nEncoderIndex < nEncoderCount; nEncoderIndex++) |
---|
348 | if(wcscmp(pImageCodecInfo[nEncoderIndex].MimeType, pszMimeType) == 0) |
---|
349 | { |
---|
350 | ClassIdentifier = pImageCodecInfo[nEncoderIndex].Clsid; |
---|
351 | return TRUE; |
---|
352 | } |
---|
353 | return FALSE; |
---|
354 | } |
---|
355 | static BOOL FindEncoderClassIdentifier(const CHAR* pszMimeType, CLSID& ClassIdentifier) |
---|
356 | { |
---|
357 | return FindEncoderClassIdentifier(CA2W(pszMimeType), ClassIdentifier); |
---|
358 | } |
---|
359 | static VOID SaveImageAsJpegFile(Gdiplus::Image* pImage, LPCTSTR pszPath, LONG nQuality) |
---|
360 | { |
---|
361 | _A(pImage && pszPath); |
---|
362 | CLSID EncoderClassIdentifier; |
---|
363 | __D(FindEncoderClassIdentifier(_T("image/jpeg"), EncoderClassIdentifier), E_UNNAMED); |
---|
364 | Gdiplus::EncoderParameters EncoderParameters; |
---|
365 | EncoderParameters.Count = 1; |
---|
366 | EncoderParameters.Parameter[0].Guid = Gdiplus::EncoderQuality; |
---|
367 | EncoderParameters.Parameter[0].NumberOfValues = 1; |
---|
368 | EncoderParameters.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong; |
---|
369 | EncoderParameters.Parameter[0].Value = &nQuality; |
---|
370 | __D(pImage->Save(CT2CW(pszPath), &EncoderClassIdentifier, &EncoderParameters) == Gdiplus::Ok, E_UNNAMED); |
---|
371 | } |
---|
372 | HRESULT Run(INT = SW_SHOWNORMAL) |
---|
373 | { |
---|
374 | CGdiPlusInitialization GdiPlusInitialization; |
---|
375 | Gdiplus::Bitmap SourceBitmap((LPCWSTR) CT2CW(m_sSourcePath)); |
---|
376 | #if _DEVELOPMENT |
---|
377 | UINT nPropertySize, nPropertyCount; |
---|
378 | SourceBitmap.GetPropertySize(&nPropertySize, &nPropertyCount); |
---|
379 | CTempBufferT<Gdiplus::PropertyItem> pPropertyItems; |
---|
380 | __D(pPropertyItems.AllocateBytes(nPropertySize), E_OUTOFMEMORY); |
---|
381 | SourceBitmap.GetAllPropertyItems(nPropertySize, nPropertyCount, pPropertyItems); |
---|
382 | for(UINT nIndex = 0; nIndex < nPropertyCount; nIndex++) |
---|
383 | { |
---|
384 | Gdiplus::PropertyItem& PropertyItem = pPropertyItems[nIndex]; |
---|
385 | CStringA sIdentifier = StringFromPropertyTag(PropertyItem.id); |
---|
386 | if(sIdentifier.IsEmpty()) |
---|
387 | sIdentifier = AtlFormatStringT<CStringA>("0x%04x", PropertyItem.id); |
---|
388 | if(sIdentifier.Left(11) == "PropertyTag") |
---|
389 | sIdentifier.Delete(0, 11); |
---|
390 | switch(PropertyItem.type) |
---|
391 | { |
---|
392 | case PropertyTagTypeByte: |
---|
393 | //_A(PropertyItem.length && !(PropertyItem.length % 1)); |
---|
394 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type Byte %d, .value %d\n"), sIdentifier, PropertyItem.length, PropertyItem.type, *((const BYTE*) PropertyItem.value)); |
---|
395 | break; |
---|
396 | case PropertyTagTypeASCII: |
---|
397 | { |
---|
398 | CStringA sValue; |
---|
399 | memcpy(sValue.GetBufferSetLength(PropertyItem.length), PropertyItem.value, PropertyItem.length); |
---|
400 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type ASCII %d, .value %hs\n"), sIdentifier, PropertyItem.length, PropertyItem.type, sValue); |
---|
401 | } |
---|
402 | break; |
---|
403 | case PropertyTagTypeShort: |
---|
404 | _A(PropertyItem.length && !(PropertyItem.length % 2)); |
---|
405 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type Short %d, .value %d\n"), sIdentifier, PropertyItem.length, PropertyItem.type, *((const SHORT*) PropertyItem.value)); |
---|
406 | break; |
---|
407 | case PropertyTagTypeLong: |
---|
408 | _A(PropertyItem.length && !(PropertyItem.length % 4)); |
---|
409 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type Long %d, .value %d\n"), sIdentifier, PropertyItem.length, PropertyItem.type, *((const LONG*) PropertyItem.value)); |
---|
410 | break; |
---|
411 | case PropertyTagTypeRational: |
---|
412 | { |
---|
413 | _A(PropertyItem.length && !(PropertyItem.length % 8)); |
---|
414 | const ULONG* pnValue = (const ULONG*) PropertyItem.value; |
---|
415 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type Rational %d, .value %d/%d\n"), sIdentifier, PropertyItem.length, PropertyItem.type, pnValue[0], pnValue[1]); |
---|
416 | } |
---|
417 | break; |
---|
418 | case PropertyTagTypeUndefined: |
---|
419 | { |
---|
420 | CStringA sValue; |
---|
421 | for(SIZE_T nIndex = 0; nIndex < PropertyItem.length && nIndex < 32; nIndex++) |
---|
422 | sValue += AtlFormatString(_T("%02X "), ((const BYTE*) PropertyItem.value)[nIndex]); |
---|
423 | sValue.TrimRight(); |
---|
424 | if(PropertyItem.length > 32) |
---|
425 | sValue += _T("..."); |
---|
426 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type Undefined %d, .value %hs\n"), sIdentifier, PropertyItem.length, PropertyItem.type, sValue); |
---|
427 | } |
---|
428 | break; |
---|
429 | case PropertyTagTypeSRational: |
---|
430 | { |
---|
431 | _A(PropertyItem.length && !(PropertyItem.length % 8)); |
---|
432 | const LONG* pnValue = (const LONG*) PropertyItem.value; |
---|
433 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type SRational %d, .value %d/%d\n"), sIdentifier, PropertyItem.length, PropertyItem.type, pnValue[0], pnValue[1]); |
---|
434 | } |
---|
435 | break; |
---|
436 | default: |
---|
437 | _Z4(atlTraceGeneral, 4, _T("PropertyItem.id %hs, .length %d, .type %d, .value 0x%p\n"), sIdentifier, PropertyItem.length, PropertyItem.type, PropertyItem.value); |
---|
438 | } |
---|
439 | } |
---|
440 | #endif // _DEVELOPMENT |
---|
441 | // NOTE: Orientation http://msdn.microsoft.com/en-us/library/windows/desktop/ms534416%28v=vs.85%29.aspx#_gdiplus_constant_propertytagorientation |
---|
442 | CSize SourceExtent(SourceBitmap.GetWidth(), SourceBitmap.GetHeight()); |
---|
443 | _tprintf(_T("Source Extent: %d x %d\n"), SourceExtent); |
---|
444 | #pragma region Rotate |
---|
445 | SHORT nOrientation = 0; |
---|
446 | UINT nOrientationPropertyItemSize = SourceBitmap.GetPropertyItemSize(PropertyTagOrientation); |
---|
447 | if(nOrientationPropertyItemSize) |
---|
448 | { |
---|
449 | CTempBufferT<Gdiplus::PropertyItem> pOrientationPropertyItem; |
---|
450 | _W(pOrientationPropertyItem.AllocateBytes(nOrientationPropertyItemSize)); |
---|
451 | pOrientationPropertyItem->id = PropertyTagOrientation; |
---|
452 | pOrientationPropertyItem->length = sizeof nOrientation; |
---|
453 | pOrientationPropertyItem->type = PropertyTagTypeShort; |
---|
454 | if(SourceBitmap.GetPropertyItem(pOrientationPropertyItem->id, nOrientationPropertyItemSize, pOrientationPropertyItem) == Gdiplus::Ok) |
---|
455 | { |
---|
456 | nOrientation = *((const SHORT*) pOrientationPropertyItem->value); |
---|
457 | _Z4(atlTraceGeneral, 4, _T("nOrientation %d\n"), nOrientation); |
---|
458 | if(nOrientation == 6) // The 0th row is the visual right side of the image, and the 0th column is the visual top. |
---|
459 | SourceBitmap.RotateFlip(Gdiplus::Rotate90FlipNone); |
---|
460 | if(nOrientation == 8) // The 0th row is the visual left side of the image, and the 0th column is the visual bottom. |
---|
461 | SourceBitmap.RotateFlip(Gdiplus::Rotate270FlipNone); |
---|
462 | if(nOrientation == 6 || nOrientation == 8) |
---|
463 | SourceExtent = CSize(SourceBitmap.GetWidth(), SourceBitmap.GetHeight()); |
---|
464 | } |
---|
465 | } |
---|
466 | #pragma endregion |
---|
467 | CSize DestinationExtent; |
---|
468 | if(SourceExtent.cx > SourceExtent.cy) |
---|
469 | { |
---|
470 | DestinationExtent.cx = 1024; |
---|
471 | DestinationExtent.cy = SourceExtent.cy * 1024 / SourceExtent.cx; |
---|
472 | } else |
---|
473 | { |
---|
474 | DestinationExtent.cy = 1024; |
---|
475 | DestinationExtent.cx = SourceExtent.cx * 1024 / SourceExtent.cy; |
---|
476 | } |
---|
477 | _tprintf(_T("Destination Extent: %d x %d\n"), DestinationExtent); |
---|
478 | Gdiplus::Bitmap DestinationBitmap(DestinationExtent.cx, DestinationExtent.cy); |
---|
479 | { |
---|
480 | Gdiplus::Graphics DestinationGraphics(&DestinationBitmap); |
---|
481 | __D(DestinationGraphics.DrawImage(&SourceBitmap, 0, 0, DestinationExtent.cx, DestinationExtent.cy) == Gdiplus::Ok, E_UNNAMED); |
---|
482 | } |
---|
483 | SaveImageAsJpegFile(&DestinationBitmap, m_sDestinationPath, 85); |
---|
484 | return S_OK; |
---|
485 | } |
---|
486 | }; |
---|
487 | |
---|
488 | //////////////////////////////////////////////////////////// |
---|
489 | // Main |
---|
490 | |
---|
491 | int _tmain(int argc, _TCHAR* argv[]) |
---|
492 | { |
---|
493 | _ATLTRY |
---|
494 | { |
---|
495 | CSingleThreadedApartment SingleThreadedApartment; |
---|
496 | CModule Module; |
---|
497 | #pragma region Parse Command Line |
---|
498 | for(INT nIndex = 1; nIndex < argc; nIndex++) |
---|
499 | { |
---|
500 | CString sArgument = argv[nIndex]; |
---|
501 | _A(!sArgument.IsEmpty()); |
---|
502 | #pragma region Switches |
---|
503 | if(_tcschr(_T("-/"), sArgument[0])) |
---|
504 | { |
---|
505 | sArgument.Delete(0); |
---|
506 | #pragma region Switch Value/Specification |
---|
507 | CString sArgumentValue; |
---|
508 | if(sArgument.GetLength() > 1) |
---|
509 | { |
---|
510 | SIZE_T nIndex = 1; |
---|
511 | if(sArgument[1] == _T(':')) |
---|
512 | nIndex++; |
---|
513 | sArgumentValue = (LPCTSTR) sArgument + nIndex; |
---|
514 | } |
---|
515 | #pragma endregion |
---|
516 | //if(_tcschr(_T("Ss"), sArgument[0])) |
---|
517 | //{ |
---|
518 | // _tprintf(_T("Option: Suppress Compressor Property Pages\n")); |
---|
519 | // Module.SetSuppressCompressorPropertyPages(); |
---|
520 | //} |
---|
521 | continue; |
---|
522 | } |
---|
523 | #pragma endregion |
---|
524 | if(sArgument.GetLength() >= 2 && sArgument[0] == _T('"') && sArgument[sArgument.GetLength() - 1] == _T('"')) |
---|
525 | sArgument = sArgument.Mid(1, sArgument.GetLength() - 2); |
---|
526 | if(!_tcslen(Module.GetSourcePath())) |
---|
527 | Module.SetSourcePath(sArgument); |
---|
528 | else if(!_tcslen(Module.GetDestinationPath())) |
---|
529 | Module.SetDestinationPath(sArgument); |
---|
530 | else |
---|
531 | __C(E_UNEXPECTED); |
---|
532 | } |
---|
533 | #pragma endregion |
---|
534 | Module.Run(); |
---|
535 | } |
---|
536 | _ATLCATCH(Exception) |
---|
537 | { |
---|
538 | _tprintf(_T("Error 0x%08x: %s\n"), (HRESULT) Exception, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r ."))); |
---|
539 | return (INT) (HRESULT) Exception; |
---|
540 | } |
---|
541 | _ATLCATCHALL() |
---|
542 | { |
---|
543 | _tprintf(_T("Fatal Error\n")); |
---|
544 | return (INT) E_FAIL; |
---|
545 | } |
---|
546 | return 0; |
---|
547 | } |
---|