Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ipe_artfile_utils/trunk/ipe_artfile_packer_ipe16_ba.c
Revision: 2
Committed: Thu Nov 8 11:19:36 2018 UTC (16 months, 2 weeks ago) by daniel-marschall
Content type: text/x-csrc
File size: 5405 byte(s)
Log Message:
Initial release to SVN

File Contents

# Content
1 /**
2 * ART file packer by Daniel Marschall, ViaThinkSoft (C) 2014-2018
3 * Supports:
4 * - Blown Away - The Interactive Game by Imagination Pilots
5 * Revision: 2018-02-15
6 **/
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdbool.h>
11 #include <string.h>
12 #include <math.h>
13
14 #include "ipe_artfile_packer_ipe16_ba.h"
15
16 #include "ipe16_artfile.h"
17 #include "ipe16_bmpimport.h"
18 #include "ipe16_lzw_encoder.h"
19
20 #define MAX_FILE 256
21
22 bool ba_pack_art(const char* szSrcFolder, FILE* fobArt, const int verbosity) {
23 bool bEverythingOK = true;
24
25 char szIndexFilename[MAX_FILE];
26 sprintf(szIndexFilename, "%s/index.txt", szSrcFolder);
27 FILE* fitIndex = fopen(szIndexFilename, "rt");
28 if (!fitIndex) {
29 fprintf(stderr, "Cannot open %s\n", szIndexFilename);
30 return false;
31 }
32
33 #define MAX_LINE 1024
34 char line[MAX_LINE];
35 int cItems = 0;
36 while (fgets(line, sizeof(line), fitIndex)) {
37 if (strlen(line) == 0) continue;
38 ++cItems;
39 }
40 if (verbosity >= 1) printf("%s contains %d entries\n", szIndexFilename, cItems); // TODO: don't print double /
41
42 Ipe16FileHeader bfh;
43 memset(&bfh, 0x00, sizeof(bfh));
44 strcpy(bfh.magic, IPE16_MAGIC_ART);
45 bfh.dummy = IPE16_MAGIC_DUMMY;
46 bfh.numHeaderEntries = cItems+1;
47
48 Ipe16PictureEntryHeader peh[cItems];
49 memset(&peh, 0x00, sizeof(peh));
50
51 BAPictureHeader ph[cItems];
52 memset(&ph, 0x00, sizeof(ph));
53
54 // We need to write the (still empty) headers, so we can use ftell() to determine the offsets correctly
55 // These headers are currently just dummies. They will be rewritten after all pictures are processed
56 fwrite(&bfh, sizeof(bfh), 1, fobArt);
57 fwrite(&peh, sizeof(peh), 1, fobArt);
58
59 fseek(fitIndex, 0, SEEK_SET);
60 int curItem = 0;
61 Ipe16LZWEncoder* lzwEncoder = NULL;
62 while (fgets(line, sizeof(line), fitIndex)) {
63 // If something fails, we discard the item, but continue in building the file!
64 #define FAIL_CONTINUE { memset(&peh[curItem], 0x00, sizeof(peh[curItem])); bEverythingOK=false; continue; }
65
66 const char* szDelimiters = " \t\r\n";
67 char* szPaletteType = strtok(&line[0], szDelimiters);
68 char* szCompressionType = strtok(NULL, szDelimiters);
69 char* szName = strtok(NULL, szDelimiters);
70 char* szFilename = strtok(NULL, szDelimiters);
71
72 if (strlen(szPaletteType) != 1) {
73 fprintf(stderr, "ERROR: Palette type (argument 1) at line %d is not valid (must be 1 char)\n", curItem+1);
74 FAIL_CONTINUE;
75 }
76 const char chPaletteType = *szPaletteType;
77
78 if ((chPaletteType != IPE16_PALETTETYPE_ATTACHED) && (chPaletteType != IPE16_PALETTETYPE_PARENT)) {
79 fprintf(stderr, "ERROR: Unknown palette type '%c' at line %d\n", chPaletteType, curItem+1);
80 FAIL_CONTINUE;
81 }
82
83 if (strlen(szCompressionType) != 1) {
84 fprintf(stderr, "ERROR: Compression type (argument 2) at line %d is not valid (must be 1 char)\n", curItem+1);
85 FAIL_CONTINUE;
86 }
87 const char chCompressionType = *szCompressionType;
88
89 if (strlen(szName) > IPE16_NAME_SIZE) {
90 fprintf(stderr, "ERROR: Name %s is too long (max %d chars allowed)\n", szName, IPE16_NAME_SIZE);
91 FAIL_CONTINUE;
92 }
93
94 strcpy(peh[curItem].name, szName);
95 peh[curItem].paletteType = chPaletteType;
96 peh[curItem].offset = ftell(fobArt);
97 peh[curItem].size = 0; // will be increased later
98
99 if (verbosity >= 1) printf("Process %s at offset %x\n", szName, peh[curItem].offset);
100
101 // Read bitmap
102
103 const bool colorTableExisting = (chPaletteType == IPE16_PALETTETYPE_ATTACHED);
104
105 char szBitmapFilename[MAX_FILE];
106 sprintf(szBitmapFilename, "%s/%s", szSrcFolder, szFilename);
107 FILE* fibBitmap = fopen(szBitmapFilename, "rb");
108 if (!fibBitmap) {
109 fprintf(stderr, "ERROR: cannot open '%s'\n", szFilename);
110 FAIL_CONTINUE;
111 }
112
113 Ipe16BmpImportData result={0};
114 if (!ipe16_bmp_import(fibBitmap, &result)) {
115 fprintf(stderr, "Error at %s: %s\n", szFilename, result.error);
116 fclose(fibBitmap);
117 ipe16_free_bmpimport_result(&result);
118 FAIL_CONTINUE;
119 }
120
121 ph[curItem].compressionType = chCompressionType;
122 ph[curItem].width = result.width;
123 ph[curItem].height = result.height;
124 fwrite(&ph[curItem], sizeof(ph[curItem]), 1, fobArt);
125 peh[curItem].size += sizeof(ph[curItem]);
126
127 // Write picture data
128
129 size_t tmpBefore = ftell(fobArt);
130 if (chCompressionType == BA_COMPRESSIONTYPE_LZW) {
131 if (!lzwEncoder) lzwEncoder = new_ipe16lzw_encoder();
132 ipe16lzw_encode(fobArt, lzwEncoder, result.bmpData, result.bmpDataSize);
133 } else if (chCompressionType == BA_COMPRESSIONTYPE_NONE) {
134 fwrite(result.bmpData, result.bmpDataSize, 1, fobArt);
135 } else {
136 fprintf(stderr, "Unknown compression type '%c' at line %d\n", chCompressionType, curItem+1);
137 fclose(fibBitmap);
138 ipe16_free_bmpimport_result(&result);
139 FAIL_CONTINUE;
140 }
141 peh[curItem].size += ftell(fobArt)-tmpBefore;
142
143 if (colorTableExisting) {
144 fwrite(result.colorTable, sizeof(*result.colorTable), 1, fobArt);
145 peh[curItem].size += sizeof(*result.colorTable);
146 }
147
148 // Free and continue
149
150 fclose(fibBitmap);
151 ipe16_free_bmpimport_result(&result);
152
153 ++curItem;
154 }
155 if (lzwEncoder) del_ipe16lzw_encoder(lzwEncoder);
156 fclose(fitIndex);
157
158 bfh.totalFileSize = ftell(fobArt);
159
160 fseek(fobArt, 0, SEEK_SET);
161 fwrite(&bfh, sizeof(bfh), 1, fobArt);
162 fwrite(&peh, sizeof(peh), 1, fobArt);
163
164 fclose(fobArt);
165
166 return bEverythingOK;
167 }

Properties

Name Value
svn:mime-type text/x-csrc