Advertisement
Reisyukaku

[Switch] ckd format

Jan 16th, 2017
722
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.87 KB | None | 0 0
  1. /*
  2. *   tgaCkd.c
  3. *       by Reisyukaku
  4. *
  5. *   Simple crude parser for CKD format used by Nintendo switch.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <stdint.h>
  11. #include <string.h>
  12.  
  13. typedef uint32_t u32;
  14. typedef uint16_t u16;
  15. typedef uint8_t u8;
  16.  
  17. //Format is similar to Gfx2
  18. typedef struct{
  19.     u32 magic;
  20.     char formatMagic[4];
  21.     u32 hdrLength;
  22.     u8 unk[0x20]; //*0x20 unk bytes*
  23. }CkdTexHead; //For some reason most values are big endian
  24.  
  25. typedef struct{
  26.     char magic[4];
  27.     u32 hdrLength;
  28.     u32 unk1;
  29.     u32 unk2;
  30. } DfvnHead;
  31.  
  32. typedef struct{
  33.     char magic[4];
  34.     u32 hdrLength;
  35.     u32 dataLength;
  36.     u32 unk1;
  37.     u32 dataOffset;
  38.     u32 unk2;
  39.     u32 dataType; //maybe??? (2=image descriptor? 3=raw data?)
  40.     u32 unk3;
  41.     u32 unk4;
  42. } HbvnHead;
  43.  
  44. //descriptor thingy:
  45. //u32 imageSize
  46. //u32 unk
  47. //u32 length
  48. //u32 width
  49. //...
  50.  
  51.  
  52. u32 swapEndian(u32 num){
  53.     return ((num>>0x18)&0xff)|((num<<8)&0xff0000)|((num>>8)&0xff00)|((num<<0x18)&0xff000000);
  54. }
  55.  
  56.  
  57. int main(int argc, char **argv){
  58.     if(argc != 2){
  59.         printf("Usage: %s <file>\n", argv[0]);
  60.         return 1;
  61.     }
  62.    
  63.     //Open file
  64.     FILE *fp;
  65.     fp = fopen(argv[1], "rb");
  66.     if(!fp){
  67.         printf("File not found!\n");
  68.         return 1;
  69.     }
  70.     fseek(fp, 0, SEEK_END);
  71.     size_t fileSize = ftell(fp);
  72.     rewind(fp);
  73.    
  74.     //Parse
  75.     CkdTexHead *ckd = malloc(sizeof(CkdTexHead));
  76.     DfvnHead *dfvn = malloc(sizeof(DfvnHead));
  77.     fread(ckd, 1, sizeof(CkdTexHead), fp);
  78.     if(swapEndian(ckd->magic) != 9){
  79.         printf("Incorrect format!\n");
  80.         return 1;
  81.     }
  82.     fseek(fp, swapEndian(ckd->hdrLength), SEEK_SET);
  83.     fread(dfvn, 1, sizeof(DfvnHead), fp);
  84.     u32 offset = swapEndian(ckd->hdrLength) + dfvn->hdrLength;
  85.  
  86.     printf(
  87.         "CKD format parser\n"
  88.         "----------------\n"
  89.         "Format: %s\n\n",
  90.         ckd->formatMagic
  91.     );
  92.    
  93.     HbvnHead *hbvn;
  94.     while(1){
  95.         //Parse HBvN
  96.         hbvn = malloc(sizeof(HbvnHead));
  97.         fread(hbvn, 1, sizeof(HbvnHead), fp);
  98.         char magic[5] = {0};
  99.         memcpy(magic, hbvn->magic, 4);
  100.         u32 magicOffset = offset;
  101.         size_t chunkSize = hbvn->dataLength + hbvn->dataOffset;
  102.         if()
  103.         printf(
  104.             "Magic: %s (@ 0x%X)\n"
  105.             "Header length: 0x%X\n"
  106.             "Data Length: 0x%X\n"
  107.             "Data offset: 0x%X\n"
  108.             "Total chunk size: 0x%X\n\n",
  109.             magic, magicOffset,
  110.             hbvn->hdrLength,
  111.             hbvn->dataOffset,
  112.             hbvn->dataLength,
  113.             chunkSize
  114.         );
  115.         free(hbvn);
  116.        
  117.         //Break if all chunks have been read
  118.         offset += chunkSize;
  119.         if(offset >= fileSize) break;
  120.         fseek(fp, offset, SEEK_SET);
  121.     }
  122.    
  123.     //Cleanup
  124.     fclose(fp);
  125.     free(ckd);
  126.     free(dfvn);
  127.    
  128.     return 0;
  129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement