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