Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: utility/bmpblk_util.c

Issue 6508006: Enable EFIv1 compression in bmpbklk_utility. (Closed) Base URL: http://git.chromium.org/git/vboot_reference.git@master
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « utility/Makefile ('k') | utility/bmpblk_utility.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <limits.h>
7 #include <stdio.h> 8 #include <stdio.h>
8 #include <string.h> 9 #include <string.h>
9 #include <sys/mman.h> 10 #include <sys/mman.h>
10 #include <sys/stat.h> 11 #include <sys/stat.h>
11 #include <sys/types.h> 12 #include <sys/types.h>
12 #include <unistd.h> 13 #include <unistd.h>
13 14
14 #include "bmpblk_util.h" 15 #include "bmpblk_util.h"
16 #include "eficompress.h"
15 17
16 18
17 // Returns pointer to buffer containing entire file, sets length. 19 // Returns pointer to buffer containing entire file, sets length.
18 static void *read_entire_file(const char *filename, size_t *length) { 20 static void *read_entire_file(const char *filename, size_t *length) {
19 int fd; 21 int fd;
20 struct stat sbuf; 22 struct stat sbuf;
21 void *ptr; 23 void *ptr;
22 24
23 *length = 0; // just in case 25 *length = 0; // just in case
24 26
(...skipping 26 matching lines...) Expand all
51 53
52 return ptr; 54 return ptr;
53 } 55 }
54 56
55 57
56 // Reclaims buffer from read_entire_file(). 58 // Reclaims buffer from read_entire_file().
57 static void discard_file(void *ptr, size_t length) { 59 static void discard_file(void *ptr, size_t length) {
58 munmap(ptr, length); 60 munmap(ptr, length);
59 } 61 }
60 62
63 //////////////////////////////////////////////////////////////////////////////
61 64
62 // Show what's inside 65 static int require_dir(const char *dirname) {
Randall Spangler 2011/02/11 23:44:02 Could move this to host/lib so we can share it wit
63 int display_bmpblock(const char *infile) { 66 struct stat sbuf;
64 char *ptr; 67
68 if (0 == stat(dirname, &sbuf)) {
69 // Something's there. Is it a directory?
70 if (S_ISDIR(sbuf.st_mode)) {
71 return 0;
72 }
73 fprintf(stderr, "%s already exists and is not a directory\n", dirname);
74 return 1;
75 }
76
77 // dirname doesn't exist. Try to create it.
78 if (ENOENT == errno) {
79 if (0 != mkdir(dirname, 0777)) {
80 fprintf(stderr, "Unable to create directory %s: %s\n",
81 dirname, strerror(errno));
82 return 1;
83 }
84 return 0;
85 }
86
87 fprintf(stderr, "Unable to stat %s: %s\n", dirname, strerror(errno));
88 return 1;
89 }
90
91
92
93 static void *do_efi_decompress(ImageInfo *img) {
94 void *ibuf;
95 void *sbuf;
96 void *obuf;
97 uint32_t isize;
98 uint32_t ssize;
99 uint32_t osize;
100 EFI_STATUS r;
101
102 ibuf = ((void *)img) + sizeof(ImageInfo);
103 isize = img->compressed_size;
104
105 r = EfiGetInfo(ibuf, isize, &osize, &ssize);
106 if (EFI_SUCCESS != r) {
107 fprintf(stderr, "EfiGetInfo() failed with code %d\n",
108 r);
109 return 0;
110 }
111
112 sbuf = malloc(ssize);
113 if (!sbuf) {
114 fprintf(stderr, "Can't allocate %d bytes: %s\n",
115 ssize,
116 strerror(errno));
117 return 0;
118 }
119
120 obuf = malloc(osize);
121 if (!obuf) {
122 fprintf(stderr, "Can't allocate %d bytes: %s\n",
123 osize,
124 strerror(errno));
125 free(sbuf);
126 return 0;
127 }
128
129 r = EfiDecompress(ibuf, isize, obuf, osize, sbuf, ssize);
130 if (r != EFI_SUCCESS) {
131 fprintf(stderr, "EfiDecompress failed with code %d\n", r);
132 free(obuf);
133 free(sbuf);
134 return 0;
135 }
136
137 free(sbuf);
138 return obuf;
139 }
140
141
142 // Show what's inside. If todir is NULL, just print. Otherwise unpack.
143 int dump_bmpblock(const char *infile, int show_as_yaml,
144 const char *todir, int overwrite) {
145 void *ptr, *data_ptr;
65 size_t length = 0; 146 size_t length = 0;
66 BmpBlockHeader *hdr; 147 BmpBlockHeader *hdr;
148 ImageInfo *img;
149 ScreenLayout *scr;
150 int loc_num;
151 int screen_num;
152 int i;
153 int offset;
154 int free_data;
155 char image_name[80];
156 char full_path_name[PATH_MAX];
157 int yfd, bfd;
158 FILE *yfp = stdout;
159 FILE *bfp = stdout;
67 160
68 ptr = (char *)read_entire_file(infile, &length); 161 ptr = (void *)read_entire_file(infile, &length);
69 if (!ptr) 162 if (!ptr)
70 return 1; 163 return 1;
71 164
72 if (length < sizeof(BmpBlockHeader)) { 165 if (length < sizeof(BmpBlockHeader)) {
73 fprintf(stderr, "File %s is too small to be a BMPBLOCK\n", infile); 166 fprintf(stderr, "File %s is too small to be a BMPBLOCK\n", infile);
74 discard_file(ptr, length); 167 discard_file(ptr, length);
75 return 1; 168 return 1;
76 } 169 }
77 170
78 if (0 != memcmp(ptr, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE)) { 171 if (0 != memcmp(ptr, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE)) {
79 fprintf(stderr, "File %s is not a BMPBLOCK\n", infile); 172 fprintf(stderr, "File %s is not a BMPBLOCK\n", infile);
80 discard_file(ptr, length); 173 discard_file(ptr, length);
81 return 1; 174 return 1;
82 } 175 }
83 176
177 if (todir) {
178 // Unpacking everything. Create the output directory if needed.
179 if (0 != require_dir(todir)) {
180 discard_file(ptr, length);
181 return 1;
182 }
183
184 // Open yaml output.
185 show_as_yaml = 1;
186
187 sprintf(full_path_name, "%s/%s", todir, "config.yaml");
188 yfd = open(full_path_name,
189 O_WRONLY | O_CREAT | O_TRUNC | (overwrite ? 0 : O_EXCL),
190 0666);
191 if (yfd < 0) {
192 fprintf(stderr, "Unable to open %s: %s\n", full_path_name,
193 strerror(errno));
194 discard_file(ptr, length);
195 return 1;
196 }
197
198 yfp = fdopen(yfd, "wb");
199 if (!yfp) {
200 fprintf(stderr, "Unable to fdopen %s: %s\n", full_path_name,
201 strerror(errno));
202 close(yfd);
203 discard_file(ptr, length);
204 return 1;
205 }
206 }
207
84 hdr = (BmpBlockHeader *)ptr; 208 hdr = (BmpBlockHeader *)ptr;
85 printf("%s:\n", infile); 209
86 printf(" version %d.%d\n", hdr->major_version, hdr->minor_version); 210 if (!show_as_yaml) {
87 printf(" %d screens\n", hdr->number_of_screenlayouts); 211 printf("%s:\n", infile);
88 printf(" %d localizations\n", hdr->number_of_localizations); 212 printf(" version %d.%d\n", hdr->major_version, hdr->minor_version);
89 printf(" %d discrete images\n", hdr->number_of_imageinfos); 213 printf(" %d screens\n", hdr->number_of_screenlayouts);
214 printf(" %d localizations\n", hdr->number_of_localizations);
215 printf(" %d discrete images\n", hdr->number_of_imageinfos);
216 discard_file(ptr, length);
217 return 0;
218 }
219
220 // Write out yaml
221 fprintf(yfp, "bmpblock: %d.%d\n", hdr->major_version, hdr->minor_version);
222 fprintf(yfp, "images:\n");
223 offset = sizeof(BmpBlockHeader) +
224 (sizeof(ScreenLayout) *
225 hdr->number_of_localizations *
226 hdr->number_of_screenlayouts);
227 for(i=0; i<hdr->number_of_imageinfos; i++) {
228 img = (ImageInfo *)(ptr + offset);
229 sprintf(image_name, "img_%08x.bmp", offset);
230 fprintf(yfp, " img_%08x: %s # %dx%d %d/%d\n", offset, image_name,
231 img->width, img->height,
232 img->compressed_size, img->original_size);
233 if (todir) {
234 sprintf(full_path_name, "%s/%s", todir, image_name);
235 bfd = open(full_path_name,
236 O_WRONLY | O_CREAT | O_TRUNC | (overwrite ? 0 : O_EXCL),
237 0666);
238 if (bfd < 0) {
239 fprintf(stderr, "Unable to open %s: %s\n", full_path_name,
240 strerror(errno));
241 fclose(yfp);
242 discard_file(ptr, length);
243 return 1;
244 }
245 bfp = fdopen(bfd, "wb");
246 if (!bfp) {
247 fprintf(stderr, "Unable to fdopen %s: %s\n", full_path_name,
248 strerror(errno));
249 close(bfd);
250 fclose(yfp);
251 discard_file(ptr, length);
252 return 1;
253 }
254 switch(img->compression) {
255 case COMPRESS_NONE:
256 data_ptr = ptr + offset + sizeof(ImageInfo);
257 free_data = 0;
258 break;
259 case COMPRESS_EFIv1:
260 data_ptr = do_efi_decompress(img);
261 if (!data_ptr) {
262 fclose(bfp);
263 fclose(yfp);
264 discard_file(ptr, length);
265 return 1;
266 }
267 free_data = 1;
268 break;
269 default:
270 fprintf(stderr, "Unsupported compression method encountered.\n");
271 fclose(bfp);
272 fclose(yfp);
273 discard_file(ptr, length);
274 return 1;
275 }
276 if (1 != fwrite(data_ptr, img->original_size, 1, bfp)) {
277 fprintf(stderr, "Unable to write %s: %s\n", full_path_name,
278 strerror(errno));
279 fclose(bfp);
280 fclose(yfp);
281 discard_file(ptr, length);
282 return 1;
283 }
284 fclose(bfp);
285 if (free_data)
286 free(data_ptr);
287 }
288 offset += sizeof(ImageInfo);
289 offset += img->compressed_size;
290 // 4-byte aligned
291 if ((offset & 3) > 0)
292 offset = (offset & ~3) + 4;
293 }
294 fprintf(yfp, "screens:\n");
295 for(loc_num = 0;
296 loc_num < hdr->number_of_localizations;
297 loc_num++) {
298 for(screen_num = 0;
299 screen_num < hdr->number_of_screenlayouts;
300 screen_num++) {
301 fprintf(yfp, " scr_%d_%d:\n", loc_num, screen_num);
302 i = loc_num * hdr->number_of_screenlayouts + screen_num;
303 offset = sizeof(BmpBlockHeader) + i * sizeof(ScreenLayout);
304 scr = (ScreenLayout *)(ptr + offset);
305 for(i=0; i<MAX_IMAGE_IN_LAYOUT; i++) {
306 if (scr->images[i].image_info_offset) {
307 fprintf(yfp, " - [%d, %d, img_%08x]\n",
308 scr->images[i].x, scr->images[i].y,
309 scr->images[i].image_info_offset);
310 }
311 }
312 }
313 }
314 fprintf(yfp, "localizations:\n");
315 for(loc_num = 0;
316 loc_num < hdr->number_of_localizations;
317 loc_num++) {
318 fprintf(yfp, " - [");
319 for(screen_num = 0;
320 screen_num < hdr->number_of_screenlayouts;
321 screen_num++) {
322 fprintf(yfp, " scr_%d_%d", loc_num, screen_num);
323 if (screen_num != hdr->number_of_screenlayouts - 1)
324 fprintf(yfp, ",");
325 }
326 fprintf(yfp, " ]\n");
327 }
328
329 if (todir)
330 fclose(yfp);
90 331
91 discard_file(ptr, length); 332 discard_file(ptr, length);
92 333
93 return 0; 334 return 0;
94 } 335 }
95 336
96 int extract_bmpblock(const char *infile, const char *dirname, int force) {
97 printf("extract parts from %s into %s %s overwriting\n",
98 infile, dirname, force ? "with" : "without");
99 printf("NOT YET IMPLEMENTED\n");
100 return 0;
101 }
OLDNEW
« no previous file with comments | « utility/Makefile ('k') | utility/bmpblk_utility.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698