Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 2005 artofcode LLC.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: mkromfs.c,v 1.2 2005/09/16 03:59:44 ray Exp $ */
18
/* Generate source data for the %rom% IODevice */
19
 
20
/*
21
 * For reasons of convenience and footprint reduction, the various postscript
22
 * source files, resources and fonts required by Ghostscript can be compiled
23
 * into the executable.
24
 *
25
 * This file takes a set of directories, and creates a compressed filesystem
26
 * image that can be compiled into the executable as static data and accessed
27
 * through the %rom% iodevice prefix
28
 */
29
 
30
#include "stdpre.h"
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
 
35
#include <zlib.h>
36
 
37
#define ROMFS_BLOCKSIZE 4096
38
#define ROMFS_CBUFSIZE ((int)((ROMFS_BLOCKSIZE) * 1.001) + 12)
39
 
40
typedef struct romfs_inode_s {
41
    char *name;
42
    struct romfs_inode_s *next, *child;
43
    unsigned int blocks;
44
    unsigned long length;
45
    unsigned long offset;
46
    unsigned long data_size;
47
    unsigned char **data;
48
    unsigned int *data_lengths;
49
} romfs_inode;
50
 
51
static int put_int32(unsigned char *p, const unsigned int q)
52
{
53
    *p++ = (q >> 24) & 0xFF;
54
    *p++ = (q >> 16) & 0xFF;
55
    *p++ = (q >>  8) & 0xFF;
56
    *p++ = (q >>  0) & 0xFF;
57
 
58
    return 4;
59
}
60
 
61
/* clear the internal memory of an inode */
62
void inode_clear(romfs_inode* node)
63
{
64
    int i;
65
 
66
    if (node) {
67
        if (node->data) {
68
            for (i = 0; i < node->blocks; i++) {
69
                if (node->data[i]) free(node->data[i]);
70
            }
71
            free(node->data);
72
        }
73
        if (node->data_lengths) free(node->data_lengths);
74
        if (node->name) free(node->name);
75
    }
76
}
77
 
78
/* write out and inode and its file data */
79
int
80
inode_write(FILE *out, romfs_inode *node)
81
{
82
    int i, offset = 0;
83
    unsigned char buf[64];
84
    unsigned char *p = buf;
85
 
86
    /* 4 byte offset to next inode */
87
    p += put_int32(p, node->offset);
88
    /* 4 byte file length */
89
    p += put_int32(p, node->length);
90
    /* 4 byte path length */
91
    p += put_int32(p, strlen(node->name));
92
 
93
    printf("writing node '%s'...\n", node->name);
94
    printf(" offset %ld\n", node->offset);
95
    printf(" length %ld\n", node->length);
96
    printf(" path length %ld\n", strlen(node->name));
97
 
98
    printf(" %d compressed blocks comprising %ld bytes\n", node->blocks, node->data_size);
99
 
100
    /* write header */
101
    offset += fwrite(buf, 3, 4, out);
102
    /* write path */
103
    offset += fwrite(node->name, 1, strlen(node->name), out);
104
    /* write block sizes */
105
    offset += fwrite(node->data_lengths, node->blocks, sizeof(*node->data_lengths), out);
106
    /* write out compressed data */
107
    for (i = 0; i < node->blocks; i++)
108
        offset += fwrite(node->data[i], 1, node->data_lengths[i], out);
109
 
110
    printf(" wrote %d bytes in all\n", offset);
111
    return offset;
112
}
113
 
114
 
115
int
116
main(int argc, char *argv[])
117
{
118
    int i, ret, block;
119
    romfs_inode *node;
120
    unsigned char *ubuf, *cbuf;
121
    unsigned long ulen, clen;
122
    unsigned long offset = 0;
123
    FILE *in, *out;
124
 
125
    ubuf = malloc(ROMFS_BLOCKSIZE);
126
    cbuf = malloc(ROMFS_CBUFSIZE);
127
 
128
    printf("compressing with %d byte blocksize (zlib output buffer %d bytes)\n",
129
        ROMFS_BLOCKSIZE, ROMFS_CBUFSIZE);
130
 
131
    out = fopen("gsromfs", "wb");
132
 
133
    /* for each path on the commandline, attach an inode */
134
    for (i = 1; i < argc; i++) {  
135
        node = calloc(1, sizeof(romfs_inode));
136
        /* get info for this file */
137
        node->name = strdup(argv[i]);
138
        in = fopen(node->name, "rb");
139
        fseek(in, 0, SEEK_END);
140
        node->length = ftell(in);
141
        node->blocks = (node->length - 1) / ROMFS_BLOCKSIZE + 1;
142
        node->data_lengths = calloc(node->blocks, sizeof(unsigned int));
143
        node->data = calloc(node->blocks, sizeof(unsigned char *));
144
        /* compress data here */
145
        fclose(in);
146
        in = fopen(node->name, "rb");
147
        block = 0;
148
        while (!feof(in)) {
149
            ulen = fread(ubuf, 1, ROMFS_BLOCKSIZE, in);
150
            if (!ulen) break;
151
            clen = ROMFS_CBUFSIZE;
152
            ret = compress(cbuf, &clen, ubuf, ulen);
153
            if (ret != Z_OK) {
154
                printf("error compressing data block!\n");
155
            }
156
            node->data_lengths[block] = clen; 
157
            node->data[block] = malloc(clen);
158
            memcpy(node->data[block], cbuf, clen);
159
            block++;
160
            node->data_size += clen;
161
        }
162
        fclose(in);
163
        node->offset = 12 + 4 * node->blocks + node->data_size + strlen(node->name);
164
        printf("inode %d (%ld/%ld bytes) '%s'\t%ld%%\n",
165
            i, node->data_size, node->length, node->name, 100*node->data_size/node->length);
166
        /* write out data for this file */
167
        inode_write(out, node);
168
        /* clean up */
169
        inode_clear(node);
170
        free(node);
171
    }
172
 
173
    free(ubuf);
174
 
175
    fclose(out);
176
 
177
    return 0;
178
}
179
 
180