Author: j Language: c
Description: Not specified Timestamp: 2009-07-16 15:10:54 +0000
View raw paste Reply
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <ctype.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <fcntl.h>
  8. #include <dirent.h>
  9. #include <sys/stat.h>
  10. #include <libgen.h>
  11.  
  12.  
  13. #define WRITE_DDS
  14.  
  15. #define DWORD uint32_t
  16.  
  17. #define DDSD_CAPS                       0x00000001
  18. #define DDSD_HEIGHT                     0x00000002
  19. #define DDSD_WIDTH                      0x00000004
  20. #define DDSD_PITCH                      0x00000008
  21. #define DDSD_PIXELFORMAT                0x00001000
  22. #define DDSD_MIPMAPCOUNT                0x00020000
  23. #define DDSD_LINEARSIZE                 0x00080000
  24. #define DDSD_DEPTH                      0x00800000
  25. #define DDPF_ALPHAPIXELS                0x00000001
  26. #define DDPF_FOURCC                     0x00000004
  27. #define DDPF_RGB                        0x00000040
  28. #define DDSCAPS_COMPLEX                 0x00000008
  29. #define DDSCAPS_TEXTURE                 0x00001000
  30. #define DDSCAPS_MIPMAP                  0x00400000
  31. #define DDSCAPS2_CUBEMAP                0x00000200
  32. #define DDSCAPS2_CUBEMAP_POSITIVEX      0x00000400
  33. #define DDSCAPS2_CUBEMAP_NEGATIVEX      0x00000800
  34. #define DDSCAPS2_CUBEMAP_POSITIVEY      0x00001000
  35. #define DDSCAPS2_CUBEMAP_NEGATIVEY      0x00002000
  36. #define DDSCAPS2_CUBEMAP_POSITIVEZ      0x00004000
  37. #define DDSCAPS2_CUBEMAP_NEGATIVEZ      0x00008000
  38. #define DDSCAPS2_VOLUME                 0x00200000
  39.  
  40. typedef struct {
  41.     DWORD dwMagic;
  42.     DWORD dwSize;
  43.     DWORD dwFlags;
  44.     DWORD dwHeight;
  45.     DWORD dwWidth;
  46.     DWORD dwPitchOrLinearSize;
  47.     DWORD dwDepth;
  48.     DWORD dwMipMapCount;
  49.     DWORD dwReserved1[11];
  50.     /*  DDPIXELFORMAT   */
  51.     struct {
  52.         DWORD dwSize;
  53.         DWORD dwFlags;
  54.         DWORD dwFourCC;
  55.         DWORD dwRGBBitCount;
  56.         DWORD dwRBitMask;
  57.         DWORD dwGBitMask;
  58.         DWORD dwBBitMask;
  59.         DWORD dwAlphaBitMask;
  60.     } sPixelFormat;
  61.     /*  DDCAPS2 */
  62.     struct {
  63.         DWORD dwCaps1;
  64.         DWORD dwCaps2;
  65.         DWORD dwDDSX;
  66.         DWORD dwReserved;
  67.     } sCaps;
  68.     DWORD dwReserved2;
  69. } DDS_header;
  70.  
  71.  
  72. typedef struct PakHeader {
  73.     DWORD magic;                /* KAPL -> "LPAK" */
  74.     float version;
  75.     DWORD startOfIndex;         /* -> 1 DWORD per file */
  76.     DWORD startOfFileEntries;   /* -> 5 DWORD per file */
  77.     DWORD startOfFileNames;     /* zero-terminated string */
  78.     DWORD startOfData;
  79.     DWORD sizeOfIndex;
  80.     DWORD sizeOfFileEntries;
  81.     DWORD sizeOfFileNames;
  82.     DWORD sizeOfData;
  83. } PakHeader;
  84.  
  85. typedef struct PakFileEntry {
  86.     DWORD fileDataPos;          /* + startOfData */
  87.     DWORD fileNamePos;          /* + startOfFileNames */
  88.     DWORD dataSize;
  89.     DWORD dataSize2;            /* real size? (always =dataSize) */
  90.     DWORD compressed;           /* compressed? (always 0) */
  91. } PakFileEntry;
  92.  
  93. /* Recursive mkdir from http://nion.modprobe.de/blog/archives/357-Recursive-directory-creation.html */
  94. static void _mkdir(const char *path)
  95. {
  96.     char opath[256];
  97.     char *p;
  98.     size_t len;
  99.  
  100.     strncpy(opath, path, sizeof(opath));
  101.     len = strlen(opath);
  102.     if (opath[len - 1] == '/')
  103.         opath[len - 1] = '\0';
  104.     for (p = opath; *p; p++)
  105.         if (*p == '/') {
  106.             *p = '\0';
  107.             if (access(opath, F_OK))
  108.                 mkdir(opath, S_IRWXU);
  109.             *p = '/';
  110.         }
  111.     if (access(opath, F_OK))    /* if path is not terminated with / */
  112.         mkdir(opath, S_IRWXU);
  113. }
  114.  
  115. /* Write out a dds file from dxt data */
  116. void write_dds(char *fileName, char *DDS_data, DWORD DDS_size)
  117. {
  118.     DDS_header header;
  119.     FILE *fout;
  120.     DWORD *int_data = (DWORD *) DDS_data;
  121.     DDS_size -= 12;
  122.     DDS_data += 12;
  123.     memset(&header, 0, sizeof(DDS_header));
  124.     header.dwMagic = ('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24);
  125.     header.sPixelFormat.dwFourCC = int_data[0];
  126.     header.dwWidth = int_data[1];
  127.     header.dwHeight = int_data[2];
  128.     header.dwSize = 124;
  129.     header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_LINEARSIZE;
  130.     header.dwPitchOrLinearSize = DDS_size;
  131.     header.sPixelFormat.dwSize = 32;
  132.     header.sPixelFormat.dwFlags = DDPF_FOURCC;
  133.     header.sCaps.dwCaps1 = DDSCAPS_TEXTURE;
  134.     fout = fopen(fileName, "wb");
  135.     fwrite(&header, sizeof(DDS_header), 1, fout);
  136.     fwrite(DDS_data, 1, DDS_size, fout);
  137.     fclose(fout);
  138. }
  139.  
  140. int main(int argc, char **argv)
  141. {
  142.     PakHeader header;
  143.     PakFileEntry *entries;
  144.     char fileName[FILENAME_MAX];
  145.     char dirName[FILENAME_MAX];
  146.     unsigned int numEntries;
  147.     unsigned int i;
  148.     int len;
  149.     FILE *outFile;
  150.     FILE *file;
  151.     char *buffer;
  152.  
  153.     if ((file = fopen("Monkey1.pak", "rb")) == NULL) {
  154.         printf("Could not open file.\n");
  155.         return -1;
  156.     }
  157.     /* Read header */
  158.     fread(&header, sizeof(PakHeader), 1, file);
  159.     /* Read file entries */
  160.     numEntries = header.sizeOfFileEntries / sizeof(PakFileEntry);
  161.     entries = malloc(header.sizeOfFileEntries);
  162.     fseek(file, header.startOfFileEntries, SEEK_SET);
  163.     fread(entries, header.sizeOfFileEntries, 1, file);
  164.     /* Dump files */
  165.     for (i = 0; i < numEntries; i++) {
  166.         fseek(file, entries[i].fileNamePos + header.startOfFileNames, SEEK_SET);
  167.         fgets(fileName, FILENAME_MAX, file);
  168.         printf("Extracting %s...\n", fileName);
  169.         strncpy(dirName, fileName, FILENAME_MAX);
  170.         _mkdir((char *) dirname(dirName));
  171.         if ((outFile = fopen(fileName, "wb")) == NULL) {
  172.             printf("Could not write to %s\n", fileName);
  173.             return -1;
  174.         }
  175.         fseek(file, entries[i].fileDataPos + header.startOfData, SEEK_SET);
  176.         buffer = malloc(entries[i].dataSize);
  177.         fread(buffer, entries[i].dataSize, 1, file);
  178.         fwrite(buffer, entries[i].dataSize, 1, outFile);
  179.         fclose(outFile);
  180. #ifdef WRITE_DDS
  181.         /* Store dxt files in dds container */
  182.         len = strlen(fileName);
  183.         if (fileName[len - 3] == 'd' && fileName[len - 2] == 'x' && fileName[len - 1] == 't') {
  184.             fileName[len - 2] = 'd';
  185.             fileName[len - 1] = 's';
  186.                         printf("Writing %s...\n", fileName);
  187.             write_dds(fileName, buffer, entries[i].dataSize);
  188.         }
  189. #endif
  190.         free(buffer);
  191.     }
  192.     fclose(file);
  193.     free(entries);
  194.     return 0;
  195. }
  196.  
View raw paste Reply