Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.1 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #include "jinclude.h"
  4. #include "jpeglib.h"
  5. #include "jversion.h"
  6. #include "jerror.h"
  7. #include "ddraw.h"
  8. #include "jpegapi.h"
  9. #include "ocmm.h"
  10. #include "ctngen.h"
  11. #include "shlwapi.h"
  12. void SHGetThumbnailSizeForThumbsDB(SIZE *psize);
  13. int vfMMXMachine = FALSE;
  14. // Global critical section to protect the JPEG libary that we are using
  15. // remove this once we remove that jpeg lib and switch to GDI+
  16. CRITICAL_SECTION g_csTNGEN;
  17. typedef struct
  18. {
  19. ULONG ulVersion;
  20. ULONG ulStreamSize;
  21. ULONG ul_x;
  22. ULONG ul_y;
  23. } jpegMiniHeader;
  24. #define TNAIL_CURRENT_VER 1
  25. CThumbnailFCNContainer::CThumbnailFCNContainer(void)
  26. {
  27. //
  28. // WARNING: for large Thumbnail_X and Thumbnail_Y values, we will need to
  29. // modify our own JPEG_BUFFER_SIZE in ctngen.cxx.
  30. //
  31. SIZE sz;
  32. SHGetThumbnailSizeForThumbsDB(&sz);
  33. Thumbnail_Quality = 75;
  34. int qual = 0;
  35. DWORD cb = sizeof(qual);
  36. SHRegGetUSValue(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
  37. TEXT("ThumbnailQuality"), NULL, &qual, &cb, FALSE, NULL, 0);
  38. if (qual >= 50 && qual <= 100) // constrain to reason
  39. {
  40. Thumbnail_Quality = qual;
  41. }
  42. Thumbnail_X = sz.cx;
  43. Thumbnail_Y = sz.cy;
  44. m_hJpegC = m_hJpegD = NULL;
  45. m_JPEGheaderSize = 0;
  46. m_JPEGheader = (BYTE *) LocalAlloc (LPTR, 1024);
  47. if (m_JPEGheader)
  48. {
  49. JPEGCompressHeader(m_JPEGheader, Thumbnail_Quality, &m_JPEGheaderSize, &m_hJpegC, JCS_RGBA);
  50. JPEGDecompressHeader(m_JPEGheader, &m_hJpegD, m_JPEGheaderSize);
  51. }
  52. }
  53. CThumbnailFCNContainer::~CThumbnailFCNContainer(void)
  54. {
  55. if (m_hJpegC)
  56. DestroyJPEGCompressHeader(m_hJpegC);
  57. if (m_hJpegD)
  58. DestroyJPEGDecompressHeader(m_hJpegD);
  59. LocalFree(m_JPEGheader);
  60. }
  61. HRESULT CThumbnailFCNContainer::EncodeThumbnail(void *pInputBitmapBits, ULONG ulWidth, ULONG ulHeight, void **ppJPEGBuffer, ULONG *pulBufferSize)
  62. {
  63. //
  64. // Allocate JPEG buffer if not allocated yet. Compressed stream should never
  65. // be larger than uncompressed thumbnail
  66. //
  67. if (*ppJPEGBuffer == NULL)
  68. {
  69. *ppJPEGBuffer = (void *) CoTaskMemAlloc (sizeof(jpegMiniHeader) + ulWidth * ulHeight * 4 + 4096);
  70. if (*ppJPEGBuffer == NULL)
  71. {
  72. return E_OUTOFMEMORY;
  73. }
  74. }
  75. ULONG ulJpegSize;
  76. EnterCriticalSection(&g_csTNGEN);
  77. {
  78. JPEGFromRGBA((unsigned char *) pInputBitmapBits,
  79. (BYTE *) *ppJPEGBuffer + sizeof(jpegMiniHeader),
  80. Thumbnail_Quality, &ulJpegSize, m_hJpegC, JCS_RGBA, ulWidth, ulHeight );
  81. }
  82. LeaveCriticalSection(&g_csTNGEN);
  83. jpegMiniHeader *pjMiniH = (jpegMiniHeader *) *ppJPEGBuffer;
  84. pjMiniH->ulVersion = TNAIL_CURRENT_VER;
  85. pjMiniH->ulStreamSize = ulJpegSize;
  86. pjMiniH->ul_x = ulWidth;
  87. pjMiniH->ul_y = ulHeight;
  88. *pulBufferSize = ulJpegSize + sizeof(jpegMiniHeader);
  89. return S_OK;
  90. }
  91. HRESULT CThumbnailFCNContainer::DecodeThumbnail(HBITMAP *phBitmap, ULONG *pulWidth, ULONG *pulHeight, void *pJPEGBuffer, ULONG ulBufferSize)
  92. {
  93. // Make sure the header is current
  94. jpegMiniHeader *pjMiniH = (jpegMiniHeader *)pJPEGBuffer;
  95. if (pjMiniH->ulVersion != TNAIL_CURRENT_VER)
  96. {
  97. return E_INVALIDARG;
  98. }
  99. // Allocate dibsection for thumbnail
  100. BITMAPINFO bmi = {0};
  101. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  102. bmi.bmiHeader.biWidth = pjMiniH->ul_x;
  103. bmi.bmiHeader.biHeight = pjMiniH->ul_y;
  104. bmi.bmiHeader.biPlanes = 1;
  105. bmi.bmiHeader.biBitCount = 32;
  106. bmi.bmiHeader.biCompression = BI_RGB;
  107. INT *ppvbits = NULL;
  108. *phBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&ppvbits, NULL, 0);
  109. EnterCriticalSection(&g_csTNGEN);
  110. {
  111. ULONG ulReturnedNumChannels;
  112. RGBAFromJPEG((BYTE *)pJPEGBuffer + sizeof(jpegMiniHeader),
  113. (BYTE *) ppvbits, m_hJpegD, pjMiniH->ulStreamSize,
  114. 1, &ulReturnedNumChannels, pjMiniH->ul_x, pjMiniH->ul_y);
  115. }
  116. LeaveCriticalSection(&g_csTNGEN);
  117. *pulWidth = pjMiniH->ul_x;
  118. *pulHeight = pjMiniH->ul_y;
  119. return S_OK;
  120. }