1
1

AdobeThumbnail.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "AdobeThumbnail.h"
  2. #include "atpch.h"
  3. #include <regex>
  4. #define MBsize 1024*1024
  5. bool AdobeThumbnail(const char* adobe_filename , const char* savejpeg_filename)
  6. {
  7. string file_ext(adobe_filename);
  8. string rs = "(.+)(\\.(?:ai|AI|indd|INDD|Indd|eps|EPS|Eps|pdf|PDF))"; // 正则字符串,exp开始的单词
  9. std::regex expression(rs); // 字符串传递给构造函数,建立正则表达式
  10. bool ret = std::regex_match(file_ext, expression);
  11. if (!ret) {
  12. // cout << "文件格式不对!\n";
  13. return ret ;
  14. }
  15. if (!IsFileExist(adobe_filename))
  16. return false ; // 文件不存在
  17. char* pch = NULL;
  18. const char* flag = "pGImg:image"; // AI 和 Indd 稍微不同
  19. /// ************* 获取 ID或者AI文档 的预览图 **************** ///
  20. FILE* adobe_file = fopen(adobe_filename, "rb");
  21. if(NULL == adobe_file){
  22. // MessageBoxA(NULL, adobe_filename, "错误File", MB_OK);
  23. return false;
  24. }
  25. size_t file_size = get_fileSize(adobe_filename); // 获得文件大小
  26. size_t bufsize = 1 * MBsize; // AI 和EPS 预览图在开头,INDD文件在末位
  27. char* filebuf = new char[bufsize]; // 文件读到缓冲
  28. // 文件小于2M 整个文件读,否则遍历读最后2M
  29. if (file_size < bufsize) {
  30. bufsize = file_size;
  31. fread(filebuf, 1, bufsize, adobe_file);
  32. if (0xF5ED0606 == *(DWORD*)filebuf) { // indd 文件开头好像都这样
  33. pch = memfind(filebuf, flag , bufsize); // INDD 可能不只一个预览图
  34. if ((pch != NULL))
  35. while ((pch != NULL) && (strlen(pch) < 10 * 1024))
  36. pch = memfind(pch + 1, flag , bufsize - (pch - filebuf));
  37. } else
  38. pch = memfind(filebuf, flag , bufsize);
  39. } else {
  40. fread(filebuf, 1, bufsize, adobe_file);
  41. // 00000000h: 06 06 ED F5 D8 1D 46 E5 BD 31 EF E7 FE 74 B7 1D ; ..眭?F褰1镧?
  42. // 00000010h: 44 4F 43 55 4D 45 4E 54 01 70 0F 00 00 05 00 00 ; DOCUMENT.p......
  43. if (0xF5ED0606 == *(DWORD*)filebuf) { // indd 文件开头好像都这样
  44. fseek(adobe_file, (file_size - bufsize), SEEK_SET);
  45. fread(filebuf, 1, bufsize, adobe_file);
  46. pch = memfind(filebuf, flag , bufsize); // INDD 可能不只一个预览图
  47. if ((pch != NULL))
  48. while ((pch != NULL) && (strlen(pch) < 10 * 1024))
  49. pch = memfind(pch + 1, flag , bufsize - (pch - filebuf));
  50. } else
  51. pch = memfind(filebuf, flag , bufsize); // AI 应该只有一个预览信息,
  52. }
  53. // 读取文件结束,关闭
  54. fclose(adobe_file);
  55. if (pch == NULL) {
  56. flag = "%AI7_Thumbnail:";
  57. size_t width, height, bitCount, Hexsize;
  58. char AI7_Thumbnail[64]; char BeginData[64]; char Hex_Bytes[64];
  59. pch = memfind(filebuf, flag , bufsize);
  60. // 检测到AI低版本预览图标记
  61. if (pch != NULL) {
  62. sscanf(pch, "%s %d %d %d\n%s %d %s\n", AI7_Thumbnail, &width, &height, &bitCount , BeginData, &Hexsize , Hex_Bytes);
  63. pch = memfind(filebuf, "Hex Bytes" , bufsize);
  64. }
  65. if (pch != NULL) { // 解码 AI7_Thumbnail 为 图片
  66. char savepng_filename[MAX_PATH]={0}; // 源图是 BMP,保存png 失真少一点
  67. strncpy(savepng_filename , savejpeg_filename, strlen(savejpeg_filename) - 4);
  68. strcat(savepng_filename, ".png");
  69. string AI7Thumb(pch + 10 , Hexsize + 1);
  70. decode_Ai7Thumb_toPng(AI7Thumb , width, height , savepng_filename);
  71. delete[] filebuf; // 释放文件缓冲
  72. return true;
  73. }
  74. };
  75. if (pch == NULL) ret = false;
  76. if (!ret) { // 没有找到,返回前
  77. delete[] filebuf; // 释放文件缓冲
  78. return ret;
  79. }
  80. strtok(pch, "\r\n");
  81. string Base64_str(pch);
  82. std::regex ex("pGImg:image>|<\\/x\\wpGImg:image>|pGImg:image=\"");
  83. std::regex en("&#xA;");
  84. // 正则删除 xmpGImg 标记和 转意换行替换回来
  85. Base64_str = std::regex_replace(Base64_str, ex, string(""));
  86. Base64_str = std::regex_replace(Base64_str, en, string("\n"));
  87. #if(AITEST)
  88. printf( "pGImg:image标记偏移: %d 在文件%s\n" , pch - filebuf , adobe_filename);
  89. #endif
  90. /// =============================== 解码一个Base64 的JPEG文件 ==============================////
  91. int b64len = Base64_str.size();
  92. int jpglen = fromBase64_Decode(Base64_str.c_str() , b64len , filebuf , b64len);
  93. FILE* jpeg_file = fopen(savejpeg_filename, "wb");
  94. fwrite(filebuf, 1 , jpglen , jpeg_file);
  95. delete[] filebuf; // 释放文件缓冲
  96. fclose(jpeg_file);
  97. return true;
  98. }
  99. bool AdobeThumbnail_W(const wchar_t* adobe_filename ,const wchar_t* savejpeg_filename ){
  100. char fromfile[MAX_PATH] = {0};
  101. char tofile[MAX_PATH] = {0};
  102. WCHARTochar(fromfile, adobe_filename);
  103. WCHARTochar(tofile, savejpeg_filename);
  104. bool ret = AdobeThumbnail(fromfile, tofile);
  105. // printf("%d\t%s\n",ret, fromfile);
  106. return ret;
  107. }
  108. int toBase64_Encode(const char* pSrc, int nLenSrc, char* pDst, int nLenDst)
  109. {
  110. int nDestLen = nLenDst;
  111. BOOL fRet = Base64Encode((BYTE*) pSrc, nLenSrc, pDst, &nDestLen, ATL_BASE64_FLAG_NONE); // 可以选择编码是否分行
  112. if (!fRet) nDestLen = 0;
  113. return (nDestLen);
  114. }
  115. int fromBase64_Decode(const char* pSrc, int nLenSrc, char* pDst, int nLenDst)
  116. {
  117. int nDestLen = nLenDst;
  118. BOOL fRet = Base64Decode((LPCSTR)pSrc, nLenSrc, (BYTE*)pDst, &nDestLen);
  119. if (!fRet) nDestLen = 0;
  120. return (nDestLen);
  121. }