home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Dita / source / resources.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  11.0 KB  |  424 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2004 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdafx.h>
  19. #include <vector>
  20. #include <algorithm>
  21. #include <string>
  22. #include <map>
  23.  
  24. #include <vd2/system/vdtypes.h>
  25. #include <vd2/system/log.h>
  26. #include <vd2/Dita/resources.h>
  27.  
  28. namespace {
  29.     typedef std::map<int, int> tStringSet;
  30.     typedef std::map<int, tStringSet> tStringSetList;
  31.     typedef std::map<int, std::vector<unsigned char> > tDialogList;
  32.     typedef std::map<int, std::vector<unsigned char> > tDialogTemplateList;
  33.  
  34.     struct VDModuleResources {
  35.         std::vector<wchar_t>    stringHeap;
  36.         tStringSetList            stringTable;
  37.         tDialogList                dialogs;
  38.         tDialogTemplateList        dlgTemplates;
  39.     };
  40.  
  41.     typedef std::map<int, VDModuleResources> tModuleResourceList;
  42.  
  43.     // Don't make this a static object -- VC7's STL is unsafe with static containers.
  44.     tModuleResourceList *g_pModuleResources;
  45. }
  46.  
  47. ///////////////////////////////////////////////////////////////////////////
  48.  
  49. void VDInitResourceSystem() {
  50.     if (!g_pModuleResources)
  51.         g_pModuleResources = new tModuleResourceList;
  52. }
  53.  
  54. void VDDeinitResourceSystem() {
  55.     delete g_pModuleResources;
  56.     g_pModuleResources = NULL;
  57. }
  58.  
  59. ///////////////////////////////////////////////////////////////////////////
  60.  
  61. // This is not a fully compliant SCSU decoder.
  62.  
  63. void VDDecompressSCSU(std::vector<wchar_t>& heap, const unsigned char *src, int len) {
  64.     enum {
  65.         kSQn        = 0x01,        // 01-08 ch        Quote from window n
  66.  
  67.         kSDX        = 0x0B,        // 0B hb lb        Define extended
  68.  
  69.         kSQU        = 0x0E,        // 0E hb lb        Quote Unicode
  70.         kSCU        = 0x0F,        //                Switch to Unicode mode
  71.  
  72.         kSCn        = 0x10,        // 10-17        Change to window n
  73.         kSDn        = 0x18,        // 18-1F b        Define window n as OffsetTable[b]
  74.  
  75.         kUCn        = 0xE0,        // E0-E7        Change to window n
  76.         kUDn        = 0xE8,        // E8-EF b        Define window n as OffsetTable[b]
  77.         kUQU        = 0xF0,        // F0            Quote
  78.         kUDX        = 0xF1,        // F1            Define extended
  79.  
  80.     };
  81.  
  82.     const unsigned static_windows[8]={0x0000,0x0080,0x0100,0x0300,0x2000,0x2080,0x2100,0x3000};
  83.     unsigned dynamic_windows[8]={0x0080,0x00c0,0x0400,0x0600,0x0900,0x3040,0x30A0,0xFF00};
  84.     int current_dynwnd = 0;
  85.     const unsigned char *srclimit = src + len;
  86.  
  87.     while(src < srclimit) {
  88.         unsigned char c = *src++;
  89.  
  90.         switch(c) {
  91.         case kSQn+0:
  92.         case kSQn+1:
  93.         case kSQn+2:
  94.         case kSQn+3:
  95.         case kSQn+4:
  96.         case kSQn+5:
  97.         case kSQn+6:
  98.         case kSQn+7:
  99.             {
  100.                 unsigned char d = *src++;
  101.                 heap.push_back(d < 0x80 ? static_windows[c-kSQn]+d : dynamic_windows[c-kSQn]+(d-0x80));
  102.             }
  103.             break;
  104.  
  105.         case kSQU:
  106.             heap.push_back(((unsigned)src[0] << 8) + src[1]);
  107.             src += 2;
  108.             break;
  109.  
  110.         case kSCn+0:
  111.         case kSCn+1:
  112.         case kSCn+2:
  113.         case kSCn+3:
  114.         case kSCn+4:
  115.         case kSCn+5:
  116.         case kSCn+6:
  117.         case kSCn+7:
  118.             current_dynwnd = (c - kSCn);
  119.             break;
  120.  
  121.         case kSDn+0:
  122.         case kSDn+1:
  123.         case kSDn+2:
  124.         case kSDn+3:
  125.         case kSDn+4:
  126.         case kSDn+5:
  127.         case kSDn+6:
  128.         case kSDn+7:
  129.             {
  130.                 unsigned char w = *src++;
  131.                 unsigned window = w<<7;
  132.  
  133.                 if (w >= 0x68) {
  134.                     if (w < 0xA8)
  135.                         window += 0xAC00;
  136.                     else switch(w) {
  137.                         case 0xF9: window = 0x00C0; break;
  138.                         case 0xFA: window = 0x0250; break;
  139.                         case 0xFB: window = 0x0370; break;
  140.                         case 0xFC: window = 0x0530; break;
  141.                         case 0xFD: window = 0x3040; break;
  142.                         case 0xFE: window = 0x30A0; break;
  143.                         case 0xFF: window = 0xFF60; break;
  144.                     }
  145.                 }
  146.  
  147.                 dynamic_windows[c - kSDn] = window;
  148.                 current_dynwnd = c-kSDn;
  149.             }
  150.             break;
  151.  
  152.         default:
  153.             heap.push_back(c < 0x80 ? c : dynamic_windows[current_dynwnd] + (c-0x80));
  154.             break;
  155.         }
  156.     }
  157.  
  158.     heap.push_back(0);
  159. }
  160.  
  161. ///////////////////////////////////////////////////////////////////////////
  162.  
  163. bool VDLoadResources(int moduleID, const void *src0, int length) {
  164.     const unsigned char *src = (const unsigned char *)src0;
  165.     const unsigned char *srclimit = src + length;
  166.  
  167.     if (!g_pModuleResources)
  168.         g_pModuleResources = new tModuleResourceList;
  169.  
  170.     // All VirtualDub resource files start with the following tag:
  171.     //    [xx|yy]
  172.     //
  173.     // xx is the write version, yy is the compatible version.
  174.  
  175.     if (src[0] != '[' || src[3] != '|' || src[6] != ']')
  176.         return false;
  177.  
  178.     int write_version = (src[1]-'0')*10 + (src[2] - '0');
  179.     int compat_version = (src[4]-'0')*10 + (src[5] - '0');
  180.  
  181.     if (compat_version > 1)
  182.         return false;    // resource is too new for us to load
  183.  
  184.     // Okay, accept it.  Begin processing chunks until we hit the end.
  185.  
  186.     VDModuleResources& module = (*g_pModuleResources)[moduleID];
  187.  
  188.     src += 64;
  189.  
  190.     while(src < srclimit) {
  191.         uint32 ckid = *(uint32 *)(src + 0);
  192.         uint32 cklen = *(uint32 *)(src + 4);
  193.         src += 8;
  194.  
  195.         if (ckid == 'SRTS') {
  196.             //    Load strings.
  197.             //
  198.             //    [uint16] string set count
  199.             //    repeat {
  200.             //        [uint16] string set id
  201.             //        [uint16] string count in string set
  202.             //        repeat {
  203.             //            [uint16]        string ID
  204.             //            [uint8/uint16]    length of compressed string
  205.             //            [variable]        string encoded using SCSU (Standard Compression Scheme for Unicode)
  206.             //        }
  207.             //    }
  208.  
  209.             const unsigned char *src2 = src;
  210.  
  211.             int strsets = *(uint16 *)src2;
  212.             src2 += 2;
  213.  
  214.             while(strsets--) {
  215.                 uint16 setid    = ((uint16 *)src2)[0];
  216.                 uint16 strings    = ((uint16 *)src2)[1];
  217.                 tStringSet& strset = module.stringTable[setid];
  218.  
  219.                 src2 += 4;
  220.  
  221.                 while(strings--) {
  222.                     uint16 strid = *(uint16 *)src2;
  223.                     src2 += 2;
  224.  
  225.                     int size = *(uint8 *)src2++;
  226.  
  227.                     if (size & 0x80) {
  228.                         VDASSERT(!(*src2 & 0x80));
  229.                         size = ((size & 0x7f) << 7) + *(uint8 *)src2++;}
  230.  
  231.                     // decompress string
  232.  
  233.                     strset[strid] = module.stringHeap.size();
  234.                     VDDecompressSCSU(module.stringHeap, src2, size);
  235.  
  236.                     src2 += size;
  237.                 }
  238.             }
  239.  
  240.         } else if (ckid == 'SGLD') {
  241.             //    Load dialogs.
  242.             //
  243.             //    [uint16] dialog count
  244.             //    repeat {
  245.             //        [uint16] dialog ID
  246.             //        [variable] dialog bytecode
  247.             //    }
  248.  
  249.             const unsigned char *src2 = src;
  250.             int dialogs = *(uint16 *)src2;
  251.             src2 += 2;
  252.  
  253.             while(dialogs--) {
  254.                 uint16 dlgid = *(uint16 *)src2;
  255.                 src2 += 2;
  256.  
  257.                 uint16 size = *(uint16 *)src2;
  258.                 src2 += 2;
  259.  
  260.                 std::vector<unsigned char>& dialog = module.dialogs[dlgid];
  261.  
  262.                 dialog.resize(size);
  263.                 std::copy(src2, src2+size, dialog.begin());
  264.                 src2 += size;
  265.             }
  266.         } else if (ckid == 'SPTD') {
  267.             //    Load dialog templates.
  268.             //
  269.             //    [uint16] dialog count
  270.             //    repeat {
  271.             //        [uint16] dialog ID
  272.             //        [variable] dialog bytecode
  273.             //    }
  274.  
  275.             const unsigned char *src2 = src;
  276.             int dialogs = *(uint16 *)src2;
  277.             src2 += 2;
  278.  
  279.             while(dialogs--) {
  280.                 uint16 dlgid = *(uint16 *)src2;
  281.                 src2 += 2;
  282.  
  283.                 uint16 size = *(uint16 *)src2;
  284.                 src2 += 2;
  285.  
  286.                 std::vector<unsigned char>& dialog = module.dlgTemplates[dlgid];
  287.  
  288.                 dialog.resize(size);
  289.                 std::copy(src2, src2+size, dialog.begin());
  290.                 src2 += size;
  291.             }
  292.         }
  293.  
  294.         src += (cklen + 3) & ~3;
  295.     }
  296.  
  297.     return true;
  298. }
  299.  
  300. void VDUnloadResources(int moduleID) {
  301.     g_pModuleResources->erase(moduleID);
  302. }
  303.  
  304. ///////////////////////////////////////////////////////////////////////////
  305.  
  306. void VDLoadStaticStringTableA(int moduleID, int tableID, const char *const *pStrings) {
  307.     VDModuleResources& modres = (*g_pModuleResources)[moduleID];
  308.     tStringSet& sset = modres.stringTable[tableID];
  309.     int id = 0;
  310.  
  311.     while(const char *s = *pStrings++) {
  312.         VDStringW ws(VDTextAToW(s));
  313.  
  314.         int pos = modres.stringHeap.size();
  315.  
  316.         modres.stringHeap.resize(pos + ws.size() + 1);
  317.         modres.stringHeap[pos + ws.size()] = 0;
  318.         ws.copy(&modres.stringHeap[pos], ws.size());
  319.  
  320.         sset[id++] = pos;
  321.     }
  322. }
  323.  
  324. void VDLoadStaticStringTableW(int moduleID, int tableID, const wchar_t *const *pStrings) {
  325.     VDModuleResources& modres = (*g_pModuleResources)[moduleID];
  326.     tStringSet& sset = modres.stringTable[tableID];
  327.     int id = 0;
  328.  
  329.     while(const wchar_t *ws = *pStrings++) {
  330.         size_t wslen = wcslen(ws);
  331.  
  332.         int pos = modres.stringHeap.size();
  333.  
  334.         modres.stringHeap.resize(pos + wslen + 1);
  335.         modres.stringHeap[pos + wslen] = 0;
  336.         std::copy(ws, ws+wslen, &modres.stringHeap[pos]);
  337.  
  338.         sset[id++] = pos;
  339.     }
  340. }
  341.  
  342. ///////////////////////////////////////////////////////////////////////////
  343.  
  344. const wchar_t *VDTryLoadString(int moduleID, int table, int id) {
  345.     tModuleResourceList::iterator itModule = (*g_pModuleResources).find(moduleID);
  346.  
  347.     if (itModule != (*g_pModuleResources).end()) {
  348.         const VDModuleResources& module = (*itModule).second;
  349.         tStringSetList::const_iterator itSS = module.stringTable.find(table);
  350.  
  351.         if (itSS != module.stringTable.end()) {
  352.             const tStringSet& strset = (*itSS).second;
  353.             tStringSet::const_iterator itS = strset.find(id);
  354.  
  355.             if (itS != strset.end()) {
  356.                 return &module.stringHeap[(*itS).second];
  357.             }
  358.         }
  359.     }
  360.  
  361.     return NULL;
  362. }
  363.  
  364. const wchar_t *VDLoadString(int moduleID, int table, int id) {
  365.     const wchar_t *s = VDTryLoadString(moduleID, table, id);
  366.  
  367.     return s ? s : L"";
  368. }
  369.  
  370. const unsigned char *VDLoadDialog(int moduleID, int id) {
  371.     tModuleResourceList::iterator itModule = (*g_pModuleResources).find(moduleID);
  372.  
  373.     if (itModule != (*g_pModuleResources).end()) {
  374.         const VDModuleResources& module = (*itModule).second;
  375.         tDialogList::const_iterator itD = module.dialogs.find(id);
  376.  
  377.         if (itD != module.dialogs.end()) {
  378.             return &(*itD).second[0];
  379.         }
  380.     }
  381.  
  382.     return NULL;
  383. }
  384.  
  385. const unsigned char *VDLoadTemplate(int moduleID, int id) {
  386.     tModuleResourceList::iterator itModule = (*g_pModuleResources).find(moduleID);
  387.  
  388.     if (itModule != (*g_pModuleResources).end()) {
  389.         const VDModuleResources& module = (*itModule).second;
  390.         tDialogList::const_iterator itD = module.dlgTemplates.find(id);
  391.  
  392.         if (itD != module.dlgTemplates.end()) {
  393.             return &(*itD).second[0];
  394.         }
  395.     }
  396.  
  397.     return NULL;
  398. }
  399.  
  400. ///////////////////////////////////////////////////////////////////////////
  401.  
  402. void VDLogAppMessage(int loglevel, int table, int id) {
  403.     VDLog(loglevel, VDStringW(VDLoadString(0, table, id)));
  404. }
  405.  
  406. void VDLogAppMessage(int loglevel, int table, int id, int args, ...) {
  407.     va_list val;
  408.     va_start(val, args);
  409.     VDLog(loglevel, VDvswprintf(VDLoadString(0, table, id), args, val));
  410.     va_end(val);
  411. }
  412.  
  413. void VDLogAppMessageLimited(int& count, int loglevel, int table, int id, int args, ...) {
  414.     ++count;
  415.     if (count == 100) {
  416.         VDLog(loglevel, VDStringW(L"(More than 100 warnings detected for this operation; ignoring remainder in interest of speed.)"));
  417.     } else if (count < 100) {
  418.         va_list val;
  419.         va_start(val, args);
  420.         VDLog(loglevel, VDvswprintf(VDLoadString(0, table, id), args, val));
  421.         va_end(val);
  422.     }
  423. }
  424.