spu: fix a wrong assumption
[pcsx_rearmed.git] / tools / psxcimg.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <zlib.h>
5
6 #define CD_FRAMESIZE_RAW 2352
7
8 struct ztab_entry {
9         unsigned int offset;
10         unsigned short size;
11 } __attribute__((packed));
12
13 int main(int argc, char *argv[])
14 {
15         unsigned char outbuf[CD_FRAMESIZE_RAW * 2];
16         unsigned char inbuf[CD_FRAMESIZE_RAW];
17         struct ztab_entry *ztable;
18         char *out_basename, *out_fname, *out_tfname;
19         FILE *fin, *fout;
20         long in_bytes, out_bytes;
21         long s, total_sectors;
22         int ret, len;
23
24         if (argc < 2) {
25                 fprintf(stderr, "usage:\n%s <cd_img> [out_basename]\n", argv[0]);
26                 return 1;
27         }
28
29         fin = fopen(argv[1], "rb");
30         if (fin == NULL) {
31                 fprintf(stderr, "fopen %s: ", argv[1]);
32                 perror(NULL);
33                 return 1;
34         }
35
36         if (argv[2] != NULL)
37                 out_basename = argv[2];
38         else
39                 out_basename = argv[1];
40
41         len = strlen(out_basename) + 3;
42         out_fname = malloc(len);
43         if (out_fname == NULL) {
44                 fprintf(stderr, "OOM\n");
45                 return 1;
46         }
47         snprintf(out_fname, len, "%s.Z", out_basename);
48
49         fout = fopen(out_fname, "wb");
50         if (fout == NULL) {
51                 fprintf(stderr, "fopen %s: ", out_fname);
52                 perror(NULL);
53                 return 1;
54         }
55
56         if (fseek(fin, 0, SEEK_END) != 0) {
57                 fprintf(stderr, "fseek failed: ");
58                 perror(NULL);
59                 return 1;
60         }
61
62         in_bytes = ftell(fin);
63         if (in_bytes % CD_FRAMESIZE_RAW) {
64                 fprintf(stderr, "warning: input size %ld is not "
65                                 "multiple of sector size\n", in_bytes);
66         }
67         total_sectors = in_bytes / CD_FRAMESIZE_RAW;
68         fseek(fin, 0, SEEK_SET);
69
70         ztable = calloc(total_sectors, sizeof(ztable[0]));
71         if (ztable == NULL) {
72                 fprintf(stderr, "OOM\n");
73                 return 1;
74         }
75
76         out_bytes = 0;
77         for (s = 0; s < total_sectors; s++) {
78                 uLongf dest_len = sizeof(outbuf);
79
80                 ret = fread(inbuf, 1, sizeof(inbuf), fin);
81                 if (ret != sizeof(inbuf)) {
82                         printf("\n");
83                         fprintf(stderr, "fread returned %d\n", ret);
84                         return 1;
85                 }
86
87                 ret = compress2(outbuf, &dest_len, inbuf, sizeof(inbuf), 9);
88                 if (ret != Z_OK) {
89                         printf("\n");
90                         fprintf(stderr, "compress2 failed: %d\n", ret);
91                         return 1;
92                 }
93
94                 ret = fwrite(outbuf, 1, dest_len, fout);
95                 if (ret != dest_len) {
96                         printf("\n");
97                         fprintf(stderr, "fwrite returned %d\n", ret);
98                         return 1;
99                 }
100
101                 ztable[s].offset = out_bytes;
102                 ztable[s].size = dest_len;
103                 out_bytes += dest_len;
104
105                 // print progress
106                 if ((s & 0x1ff) == 0) {
107                         printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
108                         printf("%3ld%% %ld/%ld", s * 100 / total_sectors, s, total_sectors);
109                         fflush(stdout);
110                 }
111         }
112
113         fclose(fin);
114         fclose(fout);
115
116         // write .table
117         len = strlen(out_fname) + 7;
118         out_tfname = malloc(len);
119         if (out_tfname == NULL) {
120                 printf("\n");
121                 fprintf(stderr, "OOM\n");
122                 return 1;
123         }
124         snprintf(out_tfname, len, "%s.table", out_fname);
125
126         fout = fopen(out_tfname, "wb");
127         if (fout == NULL) {
128                 fprintf(stderr, "fopen %s: ", out_tfname);
129                 perror(NULL);
130                 return 1;
131         }
132
133         ret = fwrite(ztable, sizeof(ztable[0]), total_sectors, fout);
134         if (ret != total_sectors) {
135                 printf("\n");
136                 fprintf(stderr, "fwrite returned %d\n", ret);
137                 return 1;
138         }
139         fclose(fout);
140
141         printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
142         printf("%3ld%% %ld/%ld\n", s * 100 / total_sectors, s, total_sectors);
143         printf("%ld bytes from %ld (%.1f%%)\n", out_bytes, in_bytes,
144                 (double)out_bytes * 100.0 / in_bytes);
145
146         return 0;
147 }