1 /** @file
2 Implementation for EFI_HII_IMAGE_PROTOCOL.
3
4
5 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include "HiiDatabase.h"
18
19
20 /**
21 Get the imageid of last image block: EFI_HII_IIBT_END_BLOCK when input
22 ImageId is zero, otherwise return the address of the
23 corresponding image block with identifier specified by ImageId.
24
25 This is a internal function.
26
27 @param ImageBlock Points to the beginning of a series of image blocks stored in order.
28 @param ImageId If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;
29 else use this id to find its corresponding image block address.
30
31 @return The image block address when input ImageId is not zero; otherwise return NULL.
32
33 **/
34 UINT8*
GetImageIdOrAddress(IN UINT8 * ImageBlock,IN OUT EFI_IMAGE_ID * ImageId)35 GetImageIdOrAddress (
36 IN UINT8 *ImageBlock,
37 IN OUT EFI_IMAGE_ID *ImageId
38 )
39 {
40 EFI_IMAGE_ID ImageIdCurrent;
41 UINT8 *ImageBlockHdr;
42 UINT8 Length8;
43 UINT16 Length16;
44 UINT32 Length32;
45 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit;
46 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit;
47 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit;
48 UINT16 Width;
49 UINT16 Height;
50
51 ASSERT (ImageBlock != NULL && ImageId != NULL);
52
53 ImageBlockHdr = ImageBlock;
54 ImageIdCurrent = 1;
55
56 while (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType != EFI_HII_IIBT_END) {
57 if (*ImageId > 0) {
58 if (*ImageId == ImageIdCurrent) {
59 //
60 // If the found image block is a duplicate block, update the ImageId to
61 // find the previous defined image block.
62 //
63 if (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType == EFI_HII_IIBT_DUPLICATE) {
64 CopyMem (ImageId, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (EFI_IMAGE_ID));
65 ASSERT (*ImageId != ImageIdCurrent);
66 ImageBlock = ImageBlockHdr;
67 ImageIdCurrent = 1;
68 continue;
69 }
70
71 return ImageBlock;
72 }
73 if (*ImageId < ImageIdCurrent) {
74 //
75 // Can not find the specified image block in this image.
76 //
77 return NULL;
78 }
79 }
80 switch (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType) {
81 case EFI_HII_IIBT_EXT1:
82 Length8 = *(UINT8*)((UINTN)ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8));
83 ImageBlock += Length8;
84 break;
85 case EFI_HII_IIBT_EXT2:
86 CopyMem (
87 &Length16,
88 (UINT8*)((UINTN)ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8)),
89 sizeof (UINT16)
90 );
91 ImageBlock += Length16;
92 break;
93 case EFI_HII_IIBT_EXT4:
94 CopyMem (
95 &Length32,
96 (UINT8*)((UINTN)ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8)),
97 sizeof (UINT32)
98 );
99 ImageBlock += Length32;
100 break;
101
102 case EFI_HII_IIBT_IMAGE_1BIT:
103 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
104 CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));
105 ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
106 BITMAP_LEN_1_BIT (Iibt1bit.Bitmap.Width, Iibt1bit.Bitmap.Height);
107 ImageIdCurrent++;
108 break;
109
110 case EFI_HII_IIBT_IMAGE_4BIT:
111 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
112 CopyMem (&Iibt4bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK));
113 ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
114 BITMAP_LEN_4_BIT (Iibt4bit.Bitmap.Width, Iibt4bit.Bitmap.Height);
115 ImageIdCurrent++;
116 break;
117
118 case EFI_HII_IIBT_IMAGE_8BIT:
119 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
120 CopyMem (&Iibt8bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK));
121 ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
122 BITMAP_LEN_8_BIT (Iibt8bit.Bitmap.Width, Iibt8bit.Bitmap.Height);
123 ImageIdCurrent++;
124 break;
125
126 case EFI_HII_IIBT_IMAGE_24BIT:
127 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
128 CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));
129 CopyMem (
130 &Height,
131 ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),
132 sizeof (UINT16)
133 );
134 ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
135 BITMAP_LEN_24_BIT (Width, Height);
136 ImageIdCurrent++;
137 break;
138
139 case EFI_HII_IIBT_DUPLICATE:
140 ImageBlock += sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);
141 ImageIdCurrent++;
142 break;
143
144 case EFI_HII_IIBT_IMAGE_JPEG:
145 CopyMem (&Length32, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT32));
146 ImageBlock += Length32;
147 ImageIdCurrent++;
148 break;
149
150 case EFI_HII_IIBT_SKIP1:
151 Length8 = *(ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK));
152 ImageBlock += sizeof (EFI_HII_IIBT_SKIP1_BLOCK);
153 ImageIdCurrent = (UINT16) (ImageIdCurrent + Length8);
154 break;
155
156 case EFI_HII_IIBT_SKIP2:
157 CopyMem (&Length16, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));
158 ImageBlock += sizeof (EFI_HII_IIBT_SKIP2_BLOCK);
159 ImageIdCurrent = (UINT16) (ImageIdCurrent + Length16);
160 break;
161
162 default:
163 //
164 // Unknown image blocks can not be skipped, processing halts.
165 //
166 ASSERT (FALSE);
167 }
168 }
169
170 //
171 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
172 //
173 if (*ImageId == 0) {
174 *ImageId = ImageIdCurrent;
175 return ImageBlock;
176 }
177
178 return NULL;
179 }
180
181
182
183 /**
184 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
185
186 This is a internal function.
187
188
189 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
190 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
191 @param PixelNum The number of pixels to be converted.
192
193
194 **/
195 VOID
CopyGopToRgbPixel(OUT EFI_HII_RGB_PIXEL * BitMapOut,IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BitMapIn,IN UINTN PixelNum)196 CopyGopToRgbPixel (
197 OUT EFI_HII_RGB_PIXEL *BitMapOut,
198 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapIn,
199 IN UINTN PixelNum
200 )
201 {
202 UINTN Index;
203
204 ASSERT (BitMapOut != NULL && BitMapIn != NULL);
205
206 for (Index = 0; Index < PixelNum; Index++) {
207 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
208 }
209 }
210
211
212 /**
213 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
214
215 This is a internal function.
216
217
218 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
219 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
220 @param PixelNum The number of pixels to be converted.
221
222
223 **/
224 VOID
CopyRgbToGopPixel(OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BitMapOut,IN EFI_HII_RGB_PIXEL * BitMapIn,IN UINTN PixelNum)225 CopyRgbToGopPixel (
226 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapOut,
227 IN EFI_HII_RGB_PIXEL *BitMapIn,
228 IN UINTN PixelNum
229 )
230 {
231 UINTN Index;
232
233 ASSERT (BitMapOut != NULL && BitMapIn != NULL);
234
235 for (Index = 0; Index < PixelNum; Index++) {
236 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
237 }
238 }
239
240
241 /**
242 Output pixels in "1 bit per pixel" format to an image.
243
244 This is a internal function.
245
246
247 @param Image Points to the image which will store the pixels.
248 @param Data Stores the value of output pixels, 0 or 1.
249 @param PaletteInfo PaletteInfo which stores the color of the output
250 pixels. First entry corresponds to color 0 and
251 second one to color 1.
252
253
254 **/
255 VOID
Output1bitPixel(IN OUT EFI_IMAGE_INPUT * Image,IN UINT8 * Data,IN EFI_HII_IMAGE_PALETTE_INFO * PaletteInfo)256 Output1bitPixel (
257 IN OUT EFI_IMAGE_INPUT *Image,
258 IN UINT8 *Data,
259 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
260 )
261 {
262 UINT16 Xpos;
263 UINT16 Ypos;
264 UINTN OffsetY;
265 UINT8 Index;
266 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;
267 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[2];
268 EFI_HII_IMAGE_PALETTE_INFO *Palette;
269 UINT16 PaletteSize;
270 UINT8 Byte;
271
272 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
273
274 BitMapPtr = Image->Bitmap;
275
276 //
277 // First entry corresponds to color 0 and second entry corresponds to color 1.
278 //
279 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
280 PaletteSize += sizeof (UINT16);
281 Palette = AllocateZeroPool (PaletteSize);
282 ASSERT (Palette != NULL);
283 CopyMem (Palette, PaletteInfo, PaletteSize);
284
285 ZeroMem (PaletteValue, sizeof (PaletteValue));
286 CopyRgbToGopPixel (&PaletteValue[0], &Palette->PaletteValue[0], 1);
287 CopyRgbToGopPixel (&PaletteValue[1], &Palette->PaletteValue[1], 1);
288 FreePool (Palette);
289
290 //
291 // Convert the pixel from one bit to corresponding color.
292 //
293 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
294 OffsetY = BITMAP_LEN_1_BIT (Image->Width, Ypos);
295 //
296 // All bits in these bytes are meaningful
297 //
298 for (Xpos = 0; Xpos < Image->Width / 8; Xpos++) {
299 Byte = *(Data + OffsetY + Xpos);
300 for (Index = 0; Index < 8; Index++) {
301 if ((Byte & (1 << Index)) != 0) {
302 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[1];
303 } else {
304 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[0];
305 }
306 }
307 }
308
309 if (Image->Width % 8 != 0) {
310 //
311 // Padding bits in this byte should be ignored.
312 //
313 Byte = *(Data + OffsetY + Xpos);
314 for (Index = 0; Index < Image->Width % 8; Index++) {
315 if ((Byte & (1 << (8 - Index - 1))) != 0) {
316 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[1];
317 } else {
318 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[0];
319 }
320 }
321 }
322 }
323 }
324
325
326 /**
327 Output pixels in "4 bit per pixel" format to an image.
328
329 This is a internal function.
330
331
332 @param Image Points to the image which will store the pixels.
333 @param Data Stores the value of output pixels, 0 ~ 15.
334 @param[in] PaletteInfo PaletteInfo which stores the color of the output
335 pixels. Each entry corresponds to a color within
336 [0, 15].
337
338
339 **/
340 VOID
Output4bitPixel(IN OUT EFI_IMAGE_INPUT * Image,IN UINT8 * Data,IN EFI_HII_IMAGE_PALETTE_INFO * PaletteInfo)341 Output4bitPixel (
342 IN OUT EFI_IMAGE_INPUT *Image,
343 IN UINT8 *Data,
344 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
345 )
346 {
347 UINT16 Xpos;
348 UINT16 Ypos;
349 UINTN OffsetY;
350 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;
351 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[16];
352 EFI_HII_IMAGE_PALETTE_INFO *Palette;
353 UINT16 PaletteSize;
354 UINT16 PaletteNum;
355 UINT8 Byte;
356
357 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
358
359 BitMapPtr = Image->Bitmap;
360
361 //
362 // The bitmap should allocate each color index starting from 0.
363 //
364 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
365 PaletteSize += sizeof (UINT16);
366 Palette = AllocateZeroPool (PaletteSize);
367 ASSERT (Palette != NULL);
368 CopyMem (Palette, PaletteInfo, PaletteSize);
369 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
370
371 ZeroMem (PaletteValue, sizeof (PaletteValue));
372 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);
373 FreePool (Palette);
374
375 //
376 // Convert the pixel from 4 bit to corresponding color.
377 //
378 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
379 OffsetY = BITMAP_LEN_4_BIT (Image->Width, Ypos);
380 //
381 // All bits in these bytes are meaningful
382 //
383 for (Xpos = 0; Xpos < Image->Width / 2; Xpos++) {
384 Byte = *(Data + OffsetY + Xpos);
385 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];
386 BitMapPtr[Ypos * Image->Width + Xpos * 2 + 1] = PaletteValue[Byte & 0x0F];
387 }
388
389 if (Image->Width % 2 != 0) {
390 //
391 // Padding bits in this byte should be ignored.
392 //
393 Byte = *(Data + OffsetY + Xpos);
394 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];
395 }
396 }
397 }
398
399
400 /**
401 Output pixels in "8 bit per pixel" format to an image.
402
403 This is a internal function.
404
405
406 @param Image Points to the image which will store the pixels.
407 @param Data Stores the value of output pixels, 0 ~ 255.
408 @param[in] PaletteInfo PaletteInfo which stores the color of the output
409 pixels. Each entry corresponds to a color within
410 [0, 255].
411
412
413 **/
414 VOID
Output8bitPixel(IN OUT EFI_IMAGE_INPUT * Image,IN UINT8 * Data,IN EFI_HII_IMAGE_PALETTE_INFO * PaletteInfo)415 Output8bitPixel (
416 IN OUT EFI_IMAGE_INPUT *Image,
417 IN UINT8 *Data,
418 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
419 )
420 {
421 UINT16 Xpos;
422 UINT16 Ypos;
423 UINTN OffsetY;
424 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;
425 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[256];
426 EFI_HII_IMAGE_PALETTE_INFO *Palette;
427 UINT16 PaletteSize;
428 UINT16 PaletteNum;
429 UINT8 Byte;
430
431 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
432
433 BitMapPtr = Image->Bitmap;
434
435 //
436 // The bitmap should allocate each color index starting from 0.
437 //
438 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
439 PaletteSize += sizeof (UINT16);
440 Palette = AllocateZeroPool (PaletteSize);
441 ASSERT (Palette != NULL);
442 CopyMem (Palette, PaletteInfo, PaletteSize);
443 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
444 ZeroMem (PaletteValue, sizeof (PaletteValue));
445 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);
446 FreePool (Palette);
447
448 //
449 // Convert the pixel from 8 bits to corresponding color.
450 //
451 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
452 OffsetY = BITMAP_LEN_8_BIT (Image->Width, Ypos);
453 //
454 // All bits are meaningful since the bitmap is 8 bits per pixel.
455 //
456 for (Xpos = 0; Xpos < Image->Width; Xpos++) {
457 Byte = *(Data + OffsetY + Xpos);
458 BitMapPtr[OffsetY + Xpos] = PaletteValue[Byte];
459 }
460 }
461
462 }
463
464
465 /**
466 Output pixels in "24 bit per pixel" format to an image.
467
468 This is a internal function.
469
470
471 @param Image Points to the image which will store the pixels.
472 @param Data Stores the color of output pixels, allowing 16.8
473 millions colors.
474
475
476 **/
477 VOID
Output24bitPixel(IN OUT EFI_IMAGE_INPUT * Image,IN EFI_HII_RGB_PIXEL * Data)478 Output24bitPixel (
479 IN OUT EFI_IMAGE_INPUT *Image,
480 IN EFI_HII_RGB_PIXEL *Data
481 )
482 {
483 UINT16 Ypos;
484 UINTN OffsetY;
485 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;
486
487 ASSERT (Image != NULL && Data != NULL);
488
489 BitMapPtr = Image->Bitmap;
490
491 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
492 OffsetY = BITMAP_LEN_8_BIT (Image->Width, Ypos);
493 CopyRgbToGopPixel (&BitMapPtr[OffsetY], &Data[OffsetY], Image->Width);
494 }
495
496 }
497
498
499 /**
500 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
501
502 This is a internal function.
503
504
505 @param BltBuffer Buffer points to bitmap data of incoming image.
506 @param BltX Specifies the offset from the left and top edge of
507 the output image of the first pixel in the image.
508 @param BltY Specifies the offset from the left and top edge of
509 the output image of the first pixel in the image.
510 @param Width Width of the incoming image, in pixels.
511 @param Height Height of the incoming image, in pixels.
512 @param Transparent If TRUE, all "off" pixels in the image will be
513 drawn using the pixel value from blt and all other
514 pixels will be copied.
515 @param Blt Buffer points to bitmap data of output image.
516
517 @retval EFI_SUCCESS The image was successfully converted.
518 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
519
520 **/
521 EFI_STATUS
ImageToBlt(IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BltBuffer,IN UINTN BltX,IN UINTN BltY,IN UINTN Width,IN UINTN Height,IN BOOLEAN Transparent,IN OUT EFI_IMAGE_OUTPUT ** Blt)522 ImageToBlt (
523 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
524 IN UINTN BltX,
525 IN UINTN BltY,
526 IN UINTN Width,
527 IN UINTN Height,
528 IN BOOLEAN Transparent,
529 IN OUT EFI_IMAGE_OUTPUT **Blt
530 )
531 {
532 EFI_IMAGE_OUTPUT *ImageOut;
533 UINTN Xpos;
534 UINTN Ypos;
535 UINTN OffsetY1; // src buffer
536 UINTN OffsetY2; // dest buffer
537 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel;
538 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel;
539
540 if (BltBuffer == NULL || Blt == NULL || *Blt == NULL) {
541 return EFI_INVALID_PARAMETER;
542 }
543
544 ImageOut = *Blt;
545
546 if (Width + BltX > ImageOut->Width) {
547 return EFI_INVALID_PARAMETER;
548 }
549 if (Height + BltY > ImageOut->Height) {
550 return EFI_INVALID_PARAMETER;
551 }
552
553 ZeroMem (&ZeroPixel, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
554
555 for (Ypos = 0; Ypos < Height; Ypos++) {
556 OffsetY1 = Width * Ypos;
557 OffsetY2 = ImageOut->Width * (BltY + Ypos);
558 for (Xpos = 0; Xpos < Width; Xpos++) {
559 SrcPixel = BltBuffer[OffsetY1 + Xpos];
560 if (Transparent) {
561 if (CompareMem (&SrcPixel, &ZeroPixel, 3) != 0) {
562 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
563 }
564 } else {
565 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
566 }
567 }
568 }
569
570 return EFI_SUCCESS;
571 }
572
573
574 /**
575 This function adds the image Image to the group of images owned by PackageList, and returns
576 a new image identifier (ImageId).
577
578 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
579 @param PackageList Handle of the package list where this image will
580 be added.
581 @param ImageId On return, contains the new image id, which is
582 unique within PackageList.
583 @param Image Points to the image.
584
585 @retval EFI_SUCCESS The new image was added successfully.
586 @retval EFI_NOT_FOUND The specified PackageList could not be found in
587 database.
588 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
589 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
590
591 **/
592 EFI_STATUS
593 EFIAPI
HiiNewImage(IN CONST EFI_HII_IMAGE_PROTOCOL * This,IN EFI_HII_HANDLE PackageList,OUT EFI_IMAGE_ID * ImageId,IN CONST EFI_IMAGE_INPUT * Image)594 HiiNewImage (
595 IN CONST EFI_HII_IMAGE_PROTOCOL *This,
596 IN EFI_HII_HANDLE PackageList,
597 OUT EFI_IMAGE_ID *ImageId,
598 IN CONST EFI_IMAGE_INPUT *Image
599 )
600 {
601 HII_DATABASE_PRIVATE_DATA *Private;
602 LIST_ENTRY *Link;
603 HII_DATABASE_RECORD *DatabaseRecord;
604 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
605 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
606 UINT8 *ImageBlock;
607 UINTN BlockSize;
608 UINT8 *NewBlock;
609 UINT8 *NewBlockPtr;
610 UINTN NewBlockSize;
611 EFI_IMAGE_INPUT *ImageIn;
612
613 if (This == NULL || ImageId == NULL || Image == NULL || Image->Bitmap == NULL) {
614 return EFI_INVALID_PARAMETER;
615 }
616
617 if (!IsHiiHandleValid (PackageList)) {
618 return EFI_NOT_FOUND;
619 }
620
621 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
622
623 //
624 // Get the specified package list
625 //
626
627 PackageListNode = NULL;
628
629 for (Link = Private->DatabaseList.ForwardLink;
630 Link != &Private->DatabaseList;
631 Link = Link->ForwardLink
632 ) {
633 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
634 if (DatabaseRecord->Handle == PackageList) {
635 PackageListNode = DatabaseRecord->PackageList;
636 break;
637 }
638 }
639
640 if (PackageListNode == NULL) {
641 return EFI_NOT_FOUND;
642 }
643
644 ImageIn = (EFI_IMAGE_INPUT *) Image;
645
646 NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
647 BITMAP_LEN_24_BIT (ImageIn->Width, ImageIn->Height);
648
649 //
650 // Get the image package in the package list,
651 // or create a new image package if image package does not exist.
652 //
653 if (PackageListNode->ImagePkg != NULL) {
654 ImagePackage = PackageListNode->ImagePkg;
655
656 //
657 // Output the image id of the incoming image being inserted, which is the
658 // image id of the EFI_HII_IIBT_END block of old image package.
659 //
660 *ImageId = 0;
661 GetImageIdOrAddress (ImagePackage->ImageBlock, ImageId);
662
663 //
664 // Update the package's image block by appending the new block to the end.
665 //
666 BlockSize = ImagePackage->ImageBlockSize + NewBlockSize;
667 ImageBlock = (UINT8 *) AllocateZeroPool (BlockSize);
668 if (ImageBlock == NULL) {
669 return EFI_OUT_OF_RESOURCES;
670 }
671 //
672 // Copy the original content.
673 //
674 CopyMem (
675 ImageBlock,
676 ImagePackage->ImageBlock,
677 ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)
678 );
679 FreePool (ImagePackage->ImageBlock);
680 ImagePackage->ImageBlock = ImageBlock;
681 ImageBlock += ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK);
682 //
683 // Temp memory to store new block.
684 //
685 NewBlock = AllocateZeroPool (NewBlockSize);
686 if (NewBlock == NULL) {
687 FreePool (ImagePackage->ImageBlock);
688 return EFI_OUT_OF_RESOURCES;
689 }
690 NewBlockPtr = NewBlock;
691
692 //
693 // Update the length record.
694 //
695 ImagePackage->ImageBlockSize = (UINT32) BlockSize;
696 ImagePackage->ImagePkgHdr.Header.Length += (UINT32) NewBlockSize;
697 PackageListNode->PackageListHdr.PackageLength += (UINT32) NewBlockSize;
698
699 } else {
700 //
701 // The specified package list does not contain image package.
702 // Create one to add this image block.
703 //
704 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
705 if (ImagePackage == NULL) {
706 return EFI_OUT_OF_RESOURCES;
707 }
708 //
709 // Output the image id of the incoming image being inserted, which is the
710 // first image block so that id is initially to one.
711 //
712 *ImageId = 1;
713 BlockSize = sizeof (EFI_HII_IIBT_END_BLOCK) + NewBlockSize;
714 //
715 // Fill in image package header.
716 //
717 ImagePackage->ImagePkgHdr.Header.Length = (UINT32) BlockSize + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
718 ImagePackage->ImagePkgHdr.Header.Type = EFI_HII_PACKAGE_IMAGES;
719 ImagePackage->ImagePkgHdr.ImageInfoOffset = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
720 ImagePackage->ImagePkgHdr.PaletteInfoOffset = 0;
721
722 //
723 // Fill in palette info.
724 //
725 ImagePackage->PaletteBlock = NULL;
726 ImagePackage->PaletteInfoSize = 0;
727
728 //
729 // Fill in image blocks.
730 //
731 ImagePackage->ImageBlockSize = (UINT32) BlockSize;
732 ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (BlockSize);
733 if (ImagePackage->ImageBlock == NULL) {
734 FreePool (ImagePackage);
735 return EFI_OUT_OF_RESOURCES;
736 }
737 ImageBlock = ImagePackage->ImageBlock;
738
739 //
740 // Temp memory to store new block.
741 //
742 NewBlock = AllocateZeroPool (NewBlockSize);
743 if (NewBlock == NULL) {
744 FreePool (ImagePackage->ImageBlock);
745 FreePool (ImagePackage);
746 return EFI_OUT_OF_RESOURCES;
747 }
748 NewBlockPtr = NewBlock;
749
750 //
751 // Insert this image package.
752 //
753 PackageListNode->ImagePkg = ImagePackage;
754 PackageListNode->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
755 }
756
757 //
758 // Append the new block here
759 //
760 if (ImageIn->Flags == EFI_IMAGE_TRANSPARENT) {
761 *NewBlock = EFI_HII_IIBT_IMAGE_24BIT_TRANS;
762 } else {
763 *NewBlock = EFI_HII_IIBT_IMAGE_24BIT;
764 }
765 NewBlock++;
766 CopyMem (NewBlock, &ImageIn->Width, sizeof (UINT16));
767 NewBlock += sizeof (UINT16);
768 CopyMem (NewBlock, &ImageIn->Height, sizeof (UINT16));
769 NewBlock += sizeof (UINT16);
770 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL *) NewBlock, ImageIn->Bitmap, ImageIn->Width * ImageIn->Height);
771
772 CopyMem (ImageBlock, NewBlockPtr, NewBlockSize);
773 FreePool (NewBlockPtr);
774
775 //
776 // Append the block end
777 //
778 ImageBlock += NewBlockSize;
779 ((EFI_HII_IIBT_END_BLOCK *) (ImageBlock))->Header.BlockType = EFI_HII_IIBT_END;
780
781 return EFI_SUCCESS;
782 }
783
784
785 /**
786 This function retrieves the image specified by ImageId which is associated with
787 the specified PackageList and copies it into the buffer specified by Image.
788
789 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
790 @param PackageList Handle of the package list where this image will
791 be searched.
792 @param ImageId The image's id,, which is unique within
793 PackageList.
794 @param Image Points to the image.
795
796 @retval EFI_SUCCESS The new image was returned successfully.
797 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
798 database. The specified PackageList is not in the database.
799 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
800 hold the image.
801 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
802 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
803 enough memory.
804
805 **/
806 EFI_STATUS
807 EFIAPI
HiiGetImage(IN CONST EFI_HII_IMAGE_PROTOCOL * This,IN EFI_HII_HANDLE PackageList,IN EFI_IMAGE_ID ImageId,OUT EFI_IMAGE_INPUT * Image)808 HiiGetImage (
809 IN CONST EFI_HII_IMAGE_PROTOCOL *This,
810 IN EFI_HII_HANDLE PackageList,
811 IN EFI_IMAGE_ID ImageId,
812 OUT EFI_IMAGE_INPUT *Image
813 )
814 {
815 HII_DATABASE_PRIVATE_DATA *Private;
816 LIST_ENTRY *Link;
817 HII_DATABASE_RECORD *DatabaseRecord;
818 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
819 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
820 UINT8 *ImageBlock;
821 EFI_IMAGE_ID LocalImageId;
822 UINT8 BlockType;
823 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit;
824 UINT16 Width;
825 UINT16 Height;
826 UINTN ImageLength;
827 BOOLEAN Flag;
828 UINT8 *PaletteInfo;
829 UINT8 PaletteIndex;
830 UINT16 PaletteSize;
831
832 if (This == NULL || Image == NULL || ImageId < 1) {
833 return EFI_INVALID_PARAMETER;
834 }
835
836 if (!IsHiiHandleValid (PackageList)) {
837 return EFI_NOT_FOUND;
838 }
839
840 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
841
842 //
843 // Get the specified package list and image package.
844 //
845 PackageListNode = NULL;
846 for (Link = Private->DatabaseList.ForwardLink;
847 Link != &Private->DatabaseList;
848 Link = Link->ForwardLink
849 ) {
850 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
851 if (DatabaseRecord->Handle == PackageList) {
852 PackageListNode = DatabaseRecord->PackageList;
853 break;
854 }
855 }
856 if (PackageListNode == NULL) {
857 return EFI_NOT_FOUND;
858 }
859 ImagePackage = PackageListNode->ImagePkg;
860 if (ImagePackage == NULL) {
861 return EFI_NOT_FOUND;
862 }
863
864 //
865 // Find the image block specified by ImageId
866 //
867 LocalImageId = ImageId;
868 ImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &LocalImageId);
869 if (ImageBlock == NULL) {
870 return EFI_NOT_FOUND;
871 }
872
873 Flag = FALSE;
874 BlockType = *ImageBlock;
875
876 switch (BlockType) {
877 case EFI_HII_IIBT_IMAGE_JPEG:
878 //
879 // BUGBUG: need to be supported as soon as image tool is designed.
880 //
881 return EFI_UNSUPPORTED;
882
883 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
884 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
885 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
886 Flag = TRUE;
887 //
888 // fall through
889 //
890 case EFI_HII_IIBT_IMAGE_1BIT:
891 case EFI_HII_IIBT_IMAGE_4BIT:
892 case EFI_HII_IIBT_IMAGE_8BIT:
893 //
894 // Use the common block code since the definition of these structures is the same.
895 //
896 CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));
897 ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
898 (Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height);
899 Image->Bitmap = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (ImageLength);
900 if (Image->Bitmap == NULL) {
901 return EFI_OUT_OF_RESOURCES;
902 }
903
904 if (Flag) {
905 Image->Flags = EFI_IMAGE_TRANSPARENT;
906 }
907 Image->Width = Iibt1bit.Bitmap.Width;
908 Image->Height = Iibt1bit.Bitmap.Height;
909
910 PaletteInfo = ImagePackage->PaletteBlock + sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
911 for (PaletteIndex = 1; PaletteIndex < Iibt1bit.PaletteIndex; PaletteIndex++) {
912 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
913 PaletteInfo += PaletteSize + sizeof (UINT16);
914 }
915 ASSERT (PaletteIndex == Iibt1bit.PaletteIndex);
916
917 //
918 // Output bitmap data
919 //
920 if (BlockType == EFI_HII_IIBT_IMAGE_1BIT || BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS) {
921 Output1bitPixel (
922 Image,
923 (UINT8 *) ((UINTN)ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8)),
924 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
925 );
926 } else if (BlockType == EFI_HII_IIBT_IMAGE_4BIT || BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS) {
927 Output4bitPixel (
928 Image,
929 (UINT8 *) ((UINTN)ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8)),
930 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
931 );
932 } else {
933 Output8bitPixel (
934 Image,
935 (UINT8 *) ((UINTN)ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8)),
936 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
937 );
938 }
939
940 return EFI_SUCCESS;
941
942 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
943 Flag = TRUE;
944 //
945 // fall through
946 //
947 case EFI_HII_IIBT_IMAGE_24BIT:
948 CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));
949 CopyMem (
950 &Height,
951 ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),
952 sizeof (UINT16)
953 );
954 ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (Width * Height);
955 Image->Bitmap = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (ImageLength);
956 if (Image->Bitmap == NULL) {
957 return EFI_OUT_OF_RESOURCES;
958 }
959
960 if (Flag) {
961 Image->Flags = EFI_IMAGE_TRANSPARENT;
962 }
963 Image->Width = Width;
964 Image->Height = Height;
965
966 //
967 // Output the bimap data directly.
968 //
969 Output24bitPixel (
970 Image,
971 (EFI_HII_RGB_PIXEL *) (ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))
972 );
973 return EFI_SUCCESS;
974
975 default:
976 return EFI_NOT_FOUND;
977 }
978 }
979
980
981 /**
982 This function updates the image specified by ImageId in the specified PackageListHandle to
983 the image specified by Image.
984
985 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
986 @param PackageList The package list containing the images.
987 @param ImageId The image's id,, which is unique within
988 PackageList.
989 @param Image Points to the image.
990
991 @retval EFI_SUCCESS The new image was updated successfully.
992 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
993 database. The specified PackageList is not in the database.
994 @retval EFI_INVALID_PARAMETER The Image was NULL.
995
996 **/
997 EFI_STATUS
998 EFIAPI
HiiSetImage(IN CONST EFI_HII_IMAGE_PROTOCOL * This,IN EFI_HII_HANDLE PackageList,IN EFI_IMAGE_ID ImageId,IN CONST EFI_IMAGE_INPUT * Image)999 HiiSetImage (
1000 IN CONST EFI_HII_IMAGE_PROTOCOL *This,
1001 IN EFI_HII_HANDLE PackageList,
1002 IN EFI_IMAGE_ID ImageId,
1003 IN CONST EFI_IMAGE_INPUT *Image
1004 )
1005 {
1006 HII_DATABASE_PRIVATE_DATA *Private;
1007 LIST_ENTRY *Link;
1008 HII_DATABASE_RECORD *DatabaseRecord;
1009 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1010 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
1011 UINT8 *ImageBlock;
1012 EFI_IMAGE_ID LocalImageId;
1013 UINT8 BlockType;
1014 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit;
1015 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit;
1016 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit;
1017 UINT16 Width;
1018 UINT16 Height;
1019 UINT32 BlockSize;
1020 UINT32 NewBlockSize;
1021 UINT32 OldBlockSize;
1022 EFI_IMAGE_INPUT *ImageIn;
1023 UINT8 *NewBlock;
1024 UINT8 *NewBlockPtr;
1025 UINT8 *Block;
1026 UINT8 *BlockPtr;
1027 UINT32 Part1Size;
1028 UINT32 Part2Size;
1029
1030 if (This == NULL || Image == NULL || ImageId < 1 || Image->Bitmap == NULL) {
1031 return EFI_INVALID_PARAMETER;
1032 }
1033
1034 if (!IsHiiHandleValid (PackageList)) {
1035 return EFI_NOT_FOUND;
1036 }
1037
1038 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1039
1040 //
1041 // Get the specified package list and image package.
1042 //
1043 PackageListNode = NULL;
1044 for (Link = Private->DatabaseList.ForwardLink;
1045 Link != &Private->DatabaseList;
1046 Link = Link->ForwardLink
1047 ) {
1048 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1049 if (DatabaseRecord->Handle == PackageList) {
1050 PackageListNode = DatabaseRecord->PackageList;
1051 break;
1052 }
1053 }
1054 if (PackageListNode == NULL) {
1055 return EFI_NOT_FOUND;
1056 }
1057 ImagePackage = PackageListNode->ImagePkg;
1058 if (ImagePackage == NULL) {
1059 return EFI_NOT_FOUND;
1060 }
1061
1062 //
1063 // Find the image block specified by ImageId
1064 //
1065 LocalImageId = ImageId;
1066 ImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &LocalImageId);
1067 if (ImageBlock == NULL) {
1068 return EFI_NOT_FOUND;
1069 }
1070
1071 BlockType = *ImageBlock;
1072
1073 //
1074 // Get the size of original image block. Use some common block code here
1075 // since the definition of some structures is the same.
1076 //
1077 switch (BlockType) {
1078 case EFI_HII_IIBT_IMAGE_JPEG:
1079 //
1080 // BUGBUG: need to be supported as soon as image tool is designed.
1081 //
1082 return EFI_UNSUPPORTED;
1083
1084 case EFI_HII_IIBT_IMAGE_1BIT:
1085 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
1086 CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));
1087 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
1088 BITMAP_LEN_1_BIT (Iibt1bit.Bitmap.Width, Iibt1bit.Bitmap.Height);
1089 break;
1090 case EFI_HII_IIBT_IMAGE_4BIT:
1091 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
1092 CopyMem (&Iibt4bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK));
1093 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
1094 BITMAP_LEN_4_BIT (Iibt4bit.Bitmap.Width, Iibt4bit.Bitmap.Height);
1095 break;
1096 case EFI_HII_IIBT_IMAGE_8BIT:
1097 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
1098 CopyMem (&Iibt8bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK));
1099 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
1100 BITMAP_LEN_8_BIT (Iibt8bit.Bitmap.Width, Iibt8bit.Bitmap.Height);
1101 break;
1102 case EFI_HII_IIBT_IMAGE_24BIT:
1103 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
1104 CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));
1105 CopyMem (
1106 &Height,
1107 ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),
1108 sizeof (UINT16)
1109 );
1110 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
1111 BITMAP_LEN_24_BIT (Width , Height);
1112 break;
1113 default:
1114 return EFI_NOT_FOUND;
1115 }
1116
1117 //
1118 // Create the new image block according to input image.
1119 //
1120 ImageIn = (EFI_IMAGE_INPUT *) Image;
1121 NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
1122 BITMAP_LEN_24_BIT (ImageIn->Width, ImageIn->Height);
1123 NewBlock = (UINT8 *) AllocateZeroPool (NewBlockSize);
1124 if (NewBlock == NULL) {
1125 return EFI_OUT_OF_RESOURCES;
1126 }
1127
1128 NewBlockPtr = NewBlock;
1129 if ((ImageIn->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
1130 *NewBlockPtr = EFI_HII_IIBT_IMAGE_24BIT_TRANS;
1131 } else {
1132 *NewBlockPtr = EFI_HII_IIBT_IMAGE_24BIT;
1133 }
1134 NewBlockPtr++;
1135
1136 CopyMem (NewBlockPtr, &ImageIn->Width, sizeof (UINT16));
1137 NewBlockPtr += sizeof (UINT16);
1138 CopyMem (NewBlockPtr, &ImageIn->Height, sizeof (UINT16));
1139 NewBlockPtr += sizeof (UINT16);
1140
1141 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL *) NewBlockPtr, ImageIn->Bitmap, ImageIn->Width * ImageIn->Height);
1142
1143 //
1144 // Adjust the image package to remove the original block firstly then add the new block.
1145 //
1146 BlockSize = ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize;
1147 Block = (UINT8 *) AllocateZeroPool (BlockSize);
1148 if (Block == NULL) {
1149 FreePool (NewBlock);
1150 return EFI_OUT_OF_RESOURCES;
1151 }
1152
1153 BlockPtr = Block;
1154 Part1Size = (UINT32) (ImageBlock - ImagePackage->ImageBlock);
1155 Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;
1156 CopyMem (BlockPtr, ImagePackage->ImageBlock, Part1Size);
1157 BlockPtr += Part1Size;
1158 CopyMem (BlockPtr, NewBlock, NewBlockSize);
1159 BlockPtr += NewBlockSize;
1160 CopyMem (BlockPtr, ImageBlock + OldBlockSize, Part2Size);
1161
1162 FreePool (ImagePackage->ImageBlock);
1163 FreePool (NewBlock);
1164 ImagePackage->ImageBlock = Block;
1165 ImagePackage->ImageBlockSize = BlockSize;
1166 ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize - OldBlockSize;
1167 PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;
1168
1169 return EFI_SUCCESS;
1170
1171 }
1172
1173
1174 /**
1175 This function renders an image to a bitmap or the screen using the specified
1176 color and options. It draws the image on an existing bitmap, allocates a new
1177 bitmap or uses the screen. The images can be clipped.
1178
1179 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1180 @param Flags Describes how the image is to be drawn.
1181 @param Image Points to the image to be displayed.
1182 @param Blt If this points to a non-NULL on entry, this points
1183 to the image, which is Width pixels wide and
1184 Height pixels high. The image will be drawn onto
1185 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1186 If this points to a NULL on entry, then a buffer
1187 will be allocated to hold the generated image and
1188 the pointer updated on exit. It is the caller's
1189 responsibility to free this buffer.
1190 @param BltX Specifies the offset from the left and top edge of
1191 the output image of the first pixel in the image.
1192 @param BltY Specifies the offset from the left and top edge of
1193 the output image of the first pixel in the image.
1194
1195 @retval EFI_SUCCESS The image was successfully drawn.
1196 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1197 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1198 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1199
1200 **/
1201 EFI_STATUS
1202 EFIAPI
HiiDrawImage(IN CONST EFI_HII_IMAGE_PROTOCOL * This,IN EFI_HII_DRAW_FLAGS Flags,IN CONST EFI_IMAGE_INPUT * Image,IN OUT EFI_IMAGE_OUTPUT ** Blt,IN UINTN BltX,IN UINTN BltY)1203 HiiDrawImage (
1204 IN CONST EFI_HII_IMAGE_PROTOCOL *This,
1205 IN EFI_HII_DRAW_FLAGS Flags,
1206 IN CONST EFI_IMAGE_INPUT *Image,
1207 IN OUT EFI_IMAGE_OUTPUT **Blt,
1208 IN UINTN BltX,
1209 IN UINTN BltY
1210 )
1211 {
1212 EFI_STATUS Status;
1213 HII_DATABASE_PRIVATE_DATA *Private;
1214 BOOLEAN Transparent;
1215 EFI_IMAGE_INPUT *ImageIn;
1216 EFI_IMAGE_OUTPUT *ImageOut;
1217 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
1218 UINTN BufferLen;
1219 UINTN Width;
1220 UINTN Height;
1221 UINTN Xpos;
1222 UINTN Ypos;
1223 UINTN OffsetY1;
1224 UINTN OffsetY2;
1225 EFI_FONT_DISPLAY_INFO *FontInfo;
1226 UINTN Index;
1227
1228 if (This == NULL || Image == NULL || Blt == NULL) {
1229 return EFI_INVALID_PARAMETER;
1230 }
1231
1232 if ((Flags & EFI_HII_DRAW_FLAG_CLIP) == EFI_HII_DRAW_FLAG_CLIP && *Blt == NULL) {
1233 return EFI_INVALID_PARAMETER;
1234 }
1235
1236 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_TRANSPARENT) {
1237 return EFI_INVALID_PARAMETER;
1238 }
1239
1240 FontInfo = NULL;
1241 ImageIn = (EFI_IMAGE_INPUT *) Image;
1242
1243 //
1244 // Check whether the image will be drawn transparently or opaquely.
1245 //
1246 Transparent = FALSE;
1247 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_TRANS) {
1248 Transparent = TRUE;
1249 } else if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE){
1250 Transparent = FALSE;
1251 } else {
1252 //
1253 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1254 // on the image's transparency setting.
1255 //
1256 if ((ImageIn->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
1257 Transparent = TRUE;
1258 }
1259 }
1260
1261 //
1262 // Image cannot be drawn transparently if Blt points to NULL on entry.
1263 // Currently output to Screen transparently is not supported, either.
1264 //
1265 if (Transparent) {
1266 if (*Blt == NULL) {
1267 return EFI_INVALID_PARAMETER;
1268 } else if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
1269 return EFI_INVALID_PARAMETER;
1270 }
1271 }
1272
1273 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1274
1275 //
1276 // When Blt points to a non-NULL on entry, this image will be drawn onto
1277 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1278 // Otherwise a new bitmap will be allocated to hold this image.
1279 //
1280 if (*Blt != NULL) {
1281 //
1282 // Clip the image by (Width, Height)
1283 //
1284
1285 Width = ImageIn->Width;
1286 Height = ImageIn->Height;
1287
1288 if (Width > (*Blt)->Width - BltX) {
1289 Width = (*Blt)->Width - BltX;
1290 }
1291 if (Height > (*Blt)->Height - BltY) {
1292 Height = (*Blt)->Height - BltY;
1293 }
1294
1295 BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
1296 BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);
1297 if (BltBuffer == NULL) {
1298 return EFI_OUT_OF_RESOURCES;
1299 }
1300
1301 if (Width == ImageIn->Width && Height == ImageIn->Height) {
1302 CopyMem (BltBuffer, ImageIn->Bitmap, BufferLen);
1303 } else {
1304 for (Ypos = 0; Ypos < Height; Ypos++) {
1305 OffsetY1 = ImageIn->Width * Ypos;
1306 OffsetY2 = Width * Ypos;
1307 for (Xpos = 0; Xpos < Width; Xpos++) {
1308 BltBuffer[OffsetY2 + Xpos] = ImageIn->Bitmap[OffsetY1 + Xpos];
1309 }
1310 }
1311 }
1312
1313 //
1314 // Draw the image to existing bitmap or screen depending on flag.
1315 //
1316 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
1317 //
1318 // Caller should make sure the current UGA console is grarphic mode.
1319 //
1320
1321 //
1322 // Write the image directly to the output device specified by Screen.
1323 //
1324 Status = (*Blt)->Image.Screen->Blt (
1325 (*Blt)->Image.Screen,
1326 BltBuffer,
1327 EfiBltBufferToVideo,
1328 0,
1329 0,
1330 BltX,
1331 BltY,
1332 Width,
1333 Height,
1334 0
1335 );
1336 } else {
1337 //
1338 // Draw the image onto the existing bitmap specified by Bitmap.
1339 //
1340 Status = ImageToBlt (
1341 BltBuffer,
1342 BltX,
1343 BltY,
1344 Width,
1345 Height,
1346 Transparent,
1347 Blt
1348 );
1349
1350 }
1351
1352 FreePool (BltBuffer);
1353 return Status;
1354
1355 } else {
1356 //
1357 // Allocate a new bitmap to hold the incoming image.
1358 //
1359 Width = ImageIn->Width + BltX;
1360 Height = ImageIn->Height + BltY;
1361
1362 BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
1363 BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);
1364 if (BltBuffer == NULL) {
1365 return EFI_OUT_OF_RESOURCES;
1366 }
1367
1368 ImageOut = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1369 if (ImageOut == NULL) {
1370 FreePool (BltBuffer);
1371 return EFI_OUT_OF_RESOURCES;
1372 }
1373 ImageOut->Width = (UINT16) Width;
1374 ImageOut->Height = (UINT16) Height;
1375 ImageOut->Image.Bitmap = BltBuffer;
1376
1377 //
1378 // BUGBUG: Now all the "blank" pixels are filled with system default background
1379 // color. Not sure if it need to be updated or not.
1380 //
1381 Status = GetSystemFont (Private, &FontInfo, NULL);
1382 if (EFI_ERROR (Status)) {
1383 FreePool (BltBuffer);
1384 FreePool (ImageOut);
1385 return Status;
1386 }
1387 ASSERT (FontInfo != NULL);
1388 for (Index = 0; Index < Width * Height; Index++) {
1389 BltBuffer[Index] = FontInfo->BackgroundColor;
1390 }
1391 FreePool (FontInfo);
1392
1393 //
1394 // Draw the incoming image to the new created image.
1395 //
1396 *Blt = ImageOut;
1397 return ImageToBlt (
1398 ImageIn->Bitmap,
1399 BltX,
1400 BltY,
1401 ImageIn->Width,
1402 ImageIn->Height,
1403 Transparent,
1404 Blt
1405 );
1406
1407 }
1408 }
1409
1410
1411 /**
1412 This function renders an image to a bitmap or the screen using the specified
1413 color and options. It draws the image on an existing bitmap, allocates a new
1414 bitmap or uses the screen. The images can be clipped.
1415
1416 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1417 @param Flags Describes how the image is to be drawn.
1418 @param PackageList The package list in the HII database to search for
1419 the specified image.
1420 @param ImageId The image's id, which is unique within
1421 PackageList.
1422 @param Blt If this points to a non-NULL on entry, this points
1423 to the image, which is Width pixels wide and
1424 Height pixels high. The image will be drawn onto
1425 this image and
1426 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1427 to a NULL on entry, then a buffer will be
1428 allocated to hold the generated image and the
1429 pointer updated on exit. It is the caller's
1430 responsibility to free this buffer.
1431 @param BltX Specifies the offset from the left and top edge of
1432 the output image of the first pixel in the image.
1433 @param BltY Specifies the offset from the left and top edge of
1434 the output image of the first pixel in the image.
1435
1436 @retval EFI_SUCCESS The image was successfully drawn.
1437 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1438 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1439 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1440 The specified PackageList is not in the database.
1441
1442 **/
1443 EFI_STATUS
1444 EFIAPI
HiiDrawImageId(IN CONST EFI_HII_IMAGE_PROTOCOL * This,IN EFI_HII_DRAW_FLAGS Flags,IN EFI_HII_HANDLE PackageList,IN EFI_IMAGE_ID ImageId,IN OUT EFI_IMAGE_OUTPUT ** Blt,IN UINTN BltX,IN UINTN BltY)1445 HiiDrawImageId (
1446 IN CONST EFI_HII_IMAGE_PROTOCOL *This,
1447 IN EFI_HII_DRAW_FLAGS Flags,
1448 IN EFI_HII_HANDLE PackageList,
1449 IN EFI_IMAGE_ID ImageId,
1450 IN OUT EFI_IMAGE_OUTPUT **Blt,
1451 IN UINTN BltX,
1452 IN UINTN BltY
1453 )
1454 {
1455 EFI_STATUS Status;
1456 EFI_IMAGE_INPUT Image;
1457
1458 //
1459 // Check input parameter.
1460 //
1461 if (This == NULL || Blt == NULL) {
1462 return EFI_INVALID_PARAMETER;
1463 }
1464
1465 if (!IsHiiHandleValid (PackageList)) {
1466 return EFI_NOT_FOUND;
1467 }
1468
1469 //
1470 // Get the specified Image.
1471 //
1472 Status = HiiGetImage (This, PackageList, ImageId, &Image);
1473 if (EFI_ERROR (Status)) {
1474 return Status;
1475 }
1476
1477 //
1478 // Draw this image.
1479 //
1480 Status = HiiDrawImage (This, Flags, &Image, Blt, BltX, BltY);
1481 if (Image.Bitmap != NULL) {
1482 FreePool (Image.Bitmap);
1483 }
1484 return Status;
1485 }
1486
1487