Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/Libeg/egimage.c

  • Property svn:executable set to *
1/*
2 * libeg/image.c
3 * Image handling functions
4 *
5 * Copyright (c) 2006 Christoph Pfisterer
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * Neither the name of Christoph Pfisterer nor the names of the
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "libegint.h"
38#include <sys/stat.h>
39#include <pexpert/i386/boot.h>
40#include "memcpy.h" // a fast memcpy
41
42#define MAX_FILE_SIZE (1024*1024*1024)
43
44
45//
46// Basic image handling
47//
48
49EG_IMAGE * egCreateImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha)
50{
51 EG_IMAGE *NewImage;
52
53 NewImage = (EG_IMAGE *) AllocateZeroPool(sizeof(EG_IMAGE));
54 if (NewImage == NULL)
55 return NULL;
56 NewImage->PixelData = (EG_PIXEL *) AllocateZeroPool(Width * Height * sizeof(EG_PIXEL));
57 if (NewImage->PixelData == NULL) {
58 FreePool(NewImage);
59 return NULL;
60 }
61
62 NewImage->Width = Width;
63 NewImage->Height = Height;
64 NewImage->HasAlpha = HasAlpha;
65 NewImage->NeedFlip = TRUE;
66 return NewImage;
67}
68
69EG_IMAGE * egCreateFilledImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha, IN EG_PIXEL *Color)
70{
71 EG_IMAGE *NewImage;
72
73 NewImage = egCreateImage(Width, Height, HasAlpha);
74 if (NewImage == NULL)
75 return NULL;
76
77 egFillImage(NewImage, Color);
78 return NewImage;
79}
80
81VOID egCopyImage(IN OUT EG_IMAGE *Image1, IN EG_IMAGE *Image2)
82{
83 if (Image1 == NULL || Image2 == NULL)
84 return ;
85
86 CopyMem(Image1->PixelData, Image2->PixelData, Image2->Width * Image2->Height * sizeof(EG_PIXEL));
87
88 Image1->Width = Image2->Width;
89 Image1->Height = Image2->Height;
90 Image1->HasAlpha = Image2->HasAlpha;
91 Image1->NeedFlip = Image2->NeedFlip;
92
93 return ;
94}
95
96EG_IMAGE * egNewImageFromImage(IN EG_IMAGE *Image)
97{
98 EG_IMAGE *NewImage;
99
100 NewImage = egCreateImage(Image->Width, Image->Height, Image->HasAlpha);
101 if (NewImage == NULL)
102 return NULL;
103
104 egCopyImage(NewImage, Image);
105
106 return NewImage;
107}
108
109EG_IMAGE * egCreateImageFromData(IN EG_PIXEL *PixelData, IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha, BOOLEAN NeedFlip)
110{
111 EG_IMAGE *NewImage;
112
113 NewImage = egCreateImage(Width, Height, HasAlpha);
114 if (NewImage == NULL)
115 return NULL;
116
117 CopyMem(NewImage->PixelData, PixelData, Width * Height * sizeof(EG_PIXEL));
118
119 NewImage->NeedFlip = NeedFlip;
120
121 return NewImage;
122}
123
124VOID egCopyScaledImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *Image)
125{
126#ifndef MAX
127#define MAX(x, y) ((x) > (y) ? (x) : (y))
128#endif
129 INTN x, x1, y, y1;
130#if UNUSED
131INTN x0, x2;
132INTN y0, y2;
133#endif
134 UINTN RatioH, RatioW, Ratio;
135 EG_PIXEL *Dest;
136
137 RatioW = (CompImage->Width << 4) / Image->Width;
138 RatioH = (CompImage->Height << 4) / Image->Height;
139
140 Ratio = MAX(RatioH,RatioW);
141
142 Dest = CompImage->PixelData;
143 for (y = 0; y < CompImage->Height; y++) {
144 y1 = (y<<4) / Ratio;
145#if UNUSED
146 y0 = ((y1 > 0)?(y1-1):y1)*Image->Width;
147 y2 = ((y1 < Image->Height)?(y1+1):y1)*Image->Width;
148#endif
149 y1 *= Image->Width;
150 for (x = 0; x < CompImage->Width; x++) {
151 x1 = (x<<4) / Ratio;
152#if UNUSED
153 x0 = (x1 > 0)?(x1-1):x1;
154 x2 = (x1 < Image->Width)?(x1+1):x1;
155#endif
156 //TODO - make sum of 5 points
157 *Dest++ = Image->PixelData[x1+y1];
158 }
159 }
160}
161
162
163EG_IMAGE * egNewScaledImage(IN EG_IMAGE *Image, IN UINTN NewW, IN UINTN NewH)
164{
165
166 EG_IMAGE *NewImage;
167
168 NewImage = egCreateImage(NewW, NewH, Image->HasAlpha);
169 if (NewImage == NULL)
170 return NULL;
171
172 egCopyScaledImage(NewImage,Image);
173
174 return NewImage;
175}
176
177VOID egFreeImage(IN EG_IMAGE *Image)
178{
179 if (Image != NULL) {
180 if (Image->PixelData != NULL)
181 FreePool(Image->PixelData);
182 FreePool(Image);
183 }
184}
185
186//
187// Basic file operations
188//
189
190EFI_STATUS egLoadFile(IN CHAR16 *FileName,
191 OUT UINT8 **FileData, OUT UINTN *FileDataLength)
192{
193 FILE*FileHandle;
194 UINT64 ReadSize;
195 UINTN BufferSize;
196 UINT8 *Buffer;
197CHAR8FileName8[1024];
198structstat buf;
199
200UnicodeStrToAsciiStr(FileName, FileName8);
201
202 FileHandle = fopen(FileName8, "rb");
203 if (!FileHandle)
204 return EFI_NOT_FOUND;
205printf("file opened\n");
206
207 fstat(fileno(FileHandle), &buf);
208 ReadSize = buf.st_size;
209if (!ReadSize)
210{
211fclose(FileHandle);
212return EFI_LOAD_ERROR;
213}
214else if (ReadSize > MAX_FILE_SIZE)
215 ReadSize = MAX_FILE_SIZE;
216printf("file size = %d\n", (INTN)ReadSize);
217
218 BufferSize = (UINTN)ReadSize; // was limited to 1 GB above, so this is safe
219 Buffer = (UINT8 *) AllocatePool(BufferSize);
220 if (Buffer == NULL) {
221 fclose(FileHandle);
222 return EFI_OUT_OF_RESOURCES;
223 }
224printf("AllocatePool = %p\n", (VOID*)Buffer);
225
226ReadSize = fread(Buffer, 1, BufferSize, FileHandle);
227 fclose(FileHandle);
228 if (BufferSize != ReadSize) {
229 FreePool(Buffer);
230 return EFI_BAD_BUFFER_SIZE;
231 }
232printf("Buffer read successfuly\n");
233
234 *FileData = Buffer;
235 *FileDataLength = BufferSize;
236 return EFI_SUCCESS;
237}
238
239//
240// Loading images from files and embedded data
241//
242
243static CHAR16 * egFindExtension(IN CHAR16 *FileName)
244{
245 INTN i;
246
247 for (i = StrLen(FileName); i >= 0; i--) {
248 if (FileName[i] == '.')
249 return FileName + i + 1;
250 if (FileName[i] == '/' || FileName[i] == '\\')
251 break;
252 }
253 return FileName + StrLen(FileName);
254}
255
256static EG_IMAGE * egDecodeAny(IN UINT8 *FileData, IN UINTN FileDataLength,
257 IN CHAR16 *Format, IN UINTN IconSize, IN BOOLEAN WantAlpha)
258{
259 EG_DECODE_FUNC DecodeFunc;
260 EG_IMAGE *NewImage;
261
262 // dispatch by extension
263 DecodeFunc = NULL;
264 if (StrCmp(Format, L"BMP") == 0)
265 DecodeFunc = egDecodeBMP;
266 else if (StrCmp(Format, L"ICNS") == 0)
267 DecodeFunc = egDecodeICNS;
268 else if (StrCmp(Format, L"PNG" ) == 0)
269 DecodeFunc = egDecodePNG;
270
271 if (DecodeFunc == NULL)
272 return NULL;
273
274 // decode it
275 NewImage = DecodeFunc(FileData, FileDataLength, IconSize, WantAlpha);
276
277 return NewImage;
278}
279
280EG_IMAGE * egLoadImage(IN CHAR16 *FilePath, IN BOOLEAN WantAlpha)
281{
282 EFI_STATUS Status;
283 UINT8 *FileData;
284 UINTN FileDataLength;
285 EG_IMAGE *NewImage;
286
287 if (FilePath == NULL)
288 return NULL;
289
290 // load file
291printf("load file\n");
292 Status = egLoadFile(FilePath, &FileData, &FileDataLength);
293 if (EFI_ERROR(Status))
294 return NULL;
295
296 // decode it
297printf("decode it\n");
298 NewImage = egDecodeAny(FileData, FileDataLength, egFindExtension(FilePath), 128, WantAlpha);
299 FreePool(FileData);
300
301 return NewImage;
302}
303
304EG_IMAGE * egLoadIcon(IN CHAR16 *FilePath, IN UINTN IconSize)
305{
306 EFI_STATUS Status;
307 UINT8 *FileData;
308 UINTN FileDataLength;
309 EG_IMAGE *NewImage;
310
311 if (FilePath == NULL)
312 return NULL;
313
314 // load file
315 Status = egLoadFile(FilePath, &FileData, &FileDataLength);
316 if (EFI_ERROR(Status))
317 return NULL;
318
319 // decode it
320 NewImage = egDecodeAny(FileData, FileDataLength, egFindExtension(FilePath), IconSize, TRUE);
321 FreePool(FileData);
322
323 return NewImage;
324}
325
326EG_IMAGE * egDecodeImage(IN UINT8 *FileData, IN UINTN FileDataLength, IN CHAR16 *Format, IN BOOLEAN WantAlpha)
327{
328 return egDecodeAny(FileData, FileDataLength, Format, 128, WantAlpha);
329}
330
331EG_IMAGE * egPrepareEmbeddedImage(IN EG_EMBEDDED_IMAGE *EmbeddedImage, IN BOOLEAN WantAlpha)
332{
333 EG_IMAGE *NewImage;
334 UINT8 *CompData;
335 UINTN CompLen;
336 UINTN PixelCount;
337
338 // sanity check
339 if (EmbeddedImage->PixelMode > EG_MAX_EIPIXELMODE ||
340 (EmbeddedImage->CompressMode != EG_EICOMPMODE_NONE && EmbeddedImage->CompressMode != EG_EICOMPMODE_RLE))
341 return NULL;
342
343 // allocate image structure and pixel buffer
344 NewImage = egCreateImage(EmbeddedImage->Width, EmbeddedImage->Height, WantAlpha);
345 if (NewImage == NULL)
346 return NULL;
347
348 CompData = (UINT8 *)EmbeddedImage->Data; // drop const
349 CompLen = EmbeddedImage->DataLength;
350 PixelCount = EmbeddedImage->Width * EmbeddedImage->Height;
351
352 // FUTURE: for EG_EICOMPMODE_EFICOMPRESS, decompress whole data block here
353
354 if (EmbeddedImage->PixelMode == EG_EIPIXELMODE_GRAY ||
355 EmbeddedImage->PixelMode == EG_EIPIXELMODE_GRAY_ALPHA) {
356
357 // copy grayscale plane and expand
358 if (EmbeddedImage->CompressMode == EG_EICOMPMODE_RLE) {
359 egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, r), PixelCount);
360 } else {
361 egInsertPlane(CompData, PLPTR(NewImage, r), PixelCount);
362 CompData += PixelCount;
363 }
364 egCopyPlane(PLPTR(NewImage, r), PLPTR(NewImage, g), PixelCount);
365 egCopyPlane(PLPTR(NewImage, r), PLPTR(NewImage, b), PixelCount);
366
367 } else if (EmbeddedImage->PixelMode == EG_EIPIXELMODE_COLOR ||
368 EmbeddedImage->PixelMode == EG_EIPIXELMODE_COLOR_ALPHA) {
369
370 // copy color planes
371 if (EmbeddedImage->CompressMode == EG_EICOMPMODE_RLE) {
372 egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, r), PixelCount);
373 egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, g), PixelCount);
374 egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, b), PixelCount);
375 } else {
376 egInsertPlane(CompData, PLPTR(NewImage, r), PixelCount);
377 CompData += PixelCount;
378 egInsertPlane(CompData, PLPTR(NewImage, g), PixelCount);
379 CompData += PixelCount;
380 egInsertPlane(CompData, PLPTR(NewImage, b), PixelCount);
381 CompData += PixelCount;
382 }
383
384 } else {
385
386 // set color planes to black
387 egSetPlane(PLPTR(NewImage, r), 0, PixelCount);
388 egSetPlane(PLPTR(NewImage, g), 0, PixelCount);
389 egSetPlane(PLPTR(NewImage, b), 0, PixelCount);
390
391 }
392
393 if (WantAlpha && (EmbeddedImage->PixelMode == EG_EIPIXELMODE_GRAY_ALPHA ||
394 EmbeddedImage->PixelMode == EG_EIPIXELMODE_COLOR_ALPHA ||
395 EmbeddedImage->PixelMode == EG_EIPIXELMODE_ALPHA)) {
396
397 // copy alpha plane
398 if (EmbeddedImage->CompressMode == EG_EICOMPMODE_RLE) {
399 egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, a), PixelCount);
400 } else {
401 egInsertPlane(CompData, PLPTR(NewImage, a), PixelCount);
402 CompData += PixelCount;
403 }
404
405 } else {
406 egSetPlane(PLPTR(NewImage, a), WantAlpha ? 255 : 0, PixelCount);
407 }
408
409 return NewImage;
410}
411
412//
413// Compositing
414//
415
416VOID egRestrictImageArea(IN EG_IMAGE *Image,
417 IN UINTN AreaPosX, IN UINTN AreaPosY,
418 IN OUT UINTN *AreaWidth, IN OUT UINTN *AreaHeight)
419{
420 if (AreaPosX >= Image->Width || AreaPosY >= Image->Height) {
421 // out of bounds, operation has no effect
422 *AreaWidth = 0;
423 *AreaHeight = 0;
424 } else {
425 // calculate affected area
426 if (*AreaWidth > Image->Width - AreaPosX)
427 *AreaWidth = Image->Width - AreaPosX;
428 if (*AreaHeight > Image->Height - AreaPosY)
429 *AreaHeight = Image->Height - AreaPosY;
430 }
431}
432
433VOID egFillImage(IN OUT EG_IMAGE *CompImage, IN EG_PIXEL *Color)
434{
435 UINTN i;
436 EG_PIXEL FillColor;
437 EG_PIXEL *PixelPtr;
438
439 FillColor = *Color;
440 if (!CompImage->HasAlpha)
441 FillColor.a = 0;
442
443 PixelPtr = CompImage->PixelData;
444 for (i = 0; i < CompImage->Width * CompImage->Height; i++, PixelPtr++)
445 *PixelPtr = FillColor;
446}
447
448VOID egFillImageArea(IN OUT EG_IMAGE *CompImage,
449 IN UINTN AreaPosX, IN UINTN AreaPosY,
450 IN UINTN AreaWidth, IN UINTN AreaHeight,
451 IN EG_PIXEL *Color)
452{
453 UINTN x, y;
454 EG_PIXEL FillColor;
455 EG_PIXEL *PixelPtr;
456 EG_PIXEL *PixelBasePtr;
457
458 egRestrictImageArea(CompImage, AreaPosX, AreaPosY, &AreaWidth, &AreaHeight);
459
460 if (AreaWidth > 0) {
461 FillColor = *Color;
462 if (!CompImage->HasAlpha)
463 FillColor.a = 0;
464
465 PixelBasePtr = CompImage->PixelData + AreaPosY * CompImage->Width + AreaPosX;
466 for (y = 0; y < AreaHeight; y++) {
467 PixelPtr = PixelBasePtr;
468 for (x = 0; x < AreaWidth; x++, PixelPtr++)
469 *PixelPtr = FillColor;
470 PixelBasePtr += CompImage->Width;
471 }
472 }
473}
474
475VOID egRawCopy(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
476 IN UINTN Width, IN UINTN Height,
477 IN UINTN CompLineOffset, IN UINTN TopLineOffset)
478{
479 UINTN x, y;
480 EG_PIXEL *TopPtr, *CompPtr;
481
482 for (y = 0; y < Height; y++) {
483 TopPtr = TopBasePtr;
484 CompPtr = CompBasePtr;
485 for (x = 0; x < Width; x++) {
486 *CompPtr = *TopPtr;
487 TopPtr++, CompPtr++;
488 }
489 TopBasePtr += TopLineOffset;
490 CompBasePtr += CompLineOffset;
491 }
492}
493
494VOID egRawCompose(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
495 IN UINTN Width, IN UINTN Height,
496 IN UINTN CompLineOffset, IN UINTN TopLineOffset)
497{
498 UINTN x, y;
499 EG_PIXEL *TopPtr, *CompPtr;
500 UINTN Alpha;
501 UINTN RevAlpha;
502 UINTN Temp;
503
504 for (y = 0; y < Height; y++) {
505 TopPtr = TopBasePtr;
506 CompPtr = CompBasePtr;
507 for (x = 0; x < Width; x++) {
508 Alpha = TopPtr->a;
509 RevAlpha = 255 - Alpha;
510 Temp = (UINTN)CompPtr->b * RevAlpha + (UINTN)TopPtr->b * Alpha + 0x80;
511 CompPtr->b = (Temp + (Temp >> 8)) >> 8;
512 Temp = (UINTN)CompPtr->g * RevAlpha + (UINTN)TopPtr->g * Alpha + 0x80;
513 CompPtr->g = (Temp + (Temp >> 8)) >> 8;
514 Temp = (UINTN)CompPtr->r * RevAlpha + (UINTN)TopPtr->r * Alpha + 0x80;
515 CompPtr->r = (Temp + (Temp >> 8)) >> 8;
516 /*
517 CompPtr->b = ((UINTN)CompPtr->b * RevAlpha + (UINTN)TopPtr->b * Alpha) / 255;
518 CompPtr->g = ((UINTN)CompPtr->g * RevAlpha + (UINTN)TopPtr->g * Alpha) / 255;
519 CompPtr->r = ((UINTN)CompPtr->r * RevAlpha + (UINTN)TopPtr->r * Alpha) / 255;
520 */
521 TopPtr++, CompPtr++;
522 }
523 TopBasePtr += TopLineOffset;
524 CompBasePtr += CompLineOffset;
525 }
526}
527
528VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN UINTN PosX, IN UINTN PosY)
529{
530 UINTN CompWidth, CompHeight;
531
532 CompWidth = TopImage->Width;
533 CompHeight = TopImage->Height;
534 egRestrictImageArea(CompImage, PosX, PosY, &CompWidth, &CompHeight);
535
536 // compose
537 if (CompWidth > 0) {
538 if (CompImage->HasAlpha) {
539 CompImage->HasAlpha = FALSE;
540 egSetPlane(PLPTR(CompImage, a), 0, CompImage->Width * CompImage->Height);
541 }
542
543 if (TopImage->HasAlpha)
544 egRawCompose(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
545 CompWidth, CompHeight, CompImage->Width, TopImage->Width);
546 else
547 egRawCopy(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
548 CompWidth, CompHeight, CompImage->Width, TopImage->Width);
549 }
550}
551
552BOOLEAN egComposeImageStretched(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage)
553{
554#define MARGIN 0
555 UINT8*pStretchedImage;
556 UINT8*pImg;
557UINT8*pbImage , *pDiData;
558 UINTN cImgChannels;
559UINTNdeltaNewSize, deltaWinSize;
560UINTNcxImgPos, cyImgPos;
561UINTNxOld, yOld;
562 UINTNxNew, yNew;
563UINTNxImg, yImg;
564 UINTNxWin, yWin;
565UINT8r, g, b, a;
566UINTNcxImgSize, cyImgSize;
567UINT8*src, *dst;
568const INT32 cDIChannels = 3;
569 UINT16 wImgRowBytes;
570 UINT16 wDIRowBytes;
571
572
573deltaWinSize = MAX(CompImage->Width,CompImage->Height);
574cxImgSize = TopImage->Width;
575cyImgSize = TopImage->Height;
576pbImage = (UINT8*)TopImage->PixelData;
577pDiData = (UINT8*)CompImage->PixelData;
578
579{
580 deltaNewSize = deltaWinSize - 2 * MARGIN;
581 cImgChannels = (TopImage->HasAlpha) ? 4 : 3;
582
583
584 // stretch the image to it's window determined size
585
586 // the following two are the same, but the first has side-effects
587 // because of rounding
588 // if ((deltaNewSize / deltaNewSize) > (cyImgSize / cxImgSize))
589 if ((deltaNewSize * cxImgSize) > (cyImgSize * deltaNewSize))
590 {
591 deltaNewSize = deltaNewSize * cyImgSize / cxImgSize;
592 cxImgPos = MARGIN;
593 cyImgPos = (deltaWinSize - deltaNewSize) / 2;
594 }
595 else
596 {
597 deltaNewSize = deltaNewSize * cxImgSize / cyImgSize;
598 cyImgPos = MARGIN;
599 cxImgPos = (deltaWinSize - deltaNewSize) / 2;
600 }
601
602 pStretchedImage = AllocatePool (cImgChannels * deltaNewSize * deltaNewSize);
603 if (!pStretchedImage)
604 {
605 return FALSE;
606 }
607pImg = pStretchedImage;
608
609 for (yNew = 0; yNew < deltaNewSize; yNew++)
610 {
611 yOld = yNew * cyImgSize / deltaNewSize;
612 for (xNew = 0; xNew < deltaNewSize; xNew++)
613 {
614 xOld = xNew * cxImgSize / deltaNewSize;
615
616 r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);
617 g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);
618 b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);
619 *pImg++ = r;
620 *pImg++ = g;
621 *pImg++ = b;
622 if (cImgChannels == 4)
623 {
624 a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)
625 + 3);
626 *pImg++ = a;
627 }
628 }
629 }
630
631// calculate row-bytes
632
633 wImgRowBytes = cImgChannels * deltaNewSize;
634 wDIRowBytes = (unsigned short) ((cDIChannels * deltaWinSize + 3L) >> 2) << 2;
635
636 // copy image to screen
637
638 for (yImg = 0, yWin = cyImgPos; yImg < deltaNewSize; yImg++, yWin++)
639 {
640 if (yWin >= CompImage->Width - cyImgPos)
641 break;
642 src = pStretchedImage + yImg * wImgRowBytes;
643 dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
644
645 for (xImg = 0, xWin = cxImgPos; xImg < deltaNewSize; xImg++, xWin++)
646 {
647 if (xWin >= deltaWinSize - cxImgPos)
648 break;
649 r = *src++;
650 g = *src++;
651 b = *src++;
652 *dst++ = b; /* note the reverse order */
653 *dst++ = g;
654 *dst++ = r;
655 if (cImgChannels == 4)
656 {
657 a = *src++;
658 }
659 }
660 }
661
662 // free memory
663
664 if (pStretchedImage != NULL)
665 {
666 FreePool (pStretchedImage);
667 pStretchedImage = NULL;
668 }
669
670 }
671return TRUE;
672
673}
674
675VOID egFlipRB(IN EG_IMAGE *Image)
676{
677UINT32 x;
678 register UINT8 tempB;
679 if (Image->NeedFlip == TRUE)
680 {
681 for (x = 0; x < (unsigned long)(Image->Height) * (Image->Width) ; x++) {
682 tempB = Image->PixelData[x].b;
683 Image->PixelData[x].b = Image->PixelData[x].r;
684 Image->PixelData[x].r = tempB;
685 }
686 Image->NeedFlip = FALSE;
687 }
688}
689
690EG_IMAGE * egEnsureImageSize(IN EG_IMAGE *Image, IN UINTN Width, IN UINTN Height, IN EG_PIXEL *Color)
691{
692 EG_IMAGE *NewImage;
693
694 if (Image == NULL)
695 return NULL;
696 if (Image->Width == Width && Image->Height == Height)
697 return Image;
698
699 NewImage = egCreateFilledImage(Width, Height, Image->HasAlpha, Color);
700 if (NewImage == NULL) {
701 egFreeImage(Image);
702 return NULL;
703 }
704 egComposeImage(NewImage, Image, 0, 0);
705 egFreeImage(Image);
706
707 return NewImage;
708}
709
710//
711// misc internal functions
712//
713
714VOID egInsertPlane(IN UINT8 *SrcDataPtr, IN UINT8 *DestPlanePtr, IN UINTN PixelCount)
715{
716 UINTN i;
717
718 for (i = 0; i < PixelCount; i++) {
719 *DestPlanePtr = *SrcDataPtr++;
720 DestPlanePtr += 4;
721 }
722}
723
724VOID egSetPlane(IN UINT8 *DestPlanePtr, IN UINT8 Value, IN UINTN PixelCount)
725{
726 UINTN i;
727
728 for (i = 0; i < PixelCount; i++) {
729 *DestPlanePtr = Value;
730 DestPlanePtr += 4;
731 }
732}
733
734VOID egCopyPlane(IN UINT8 *SrcPlanePtr, IN UINT8 *DestPlanePtr, IN UINTN PixelCount)
735{
736 UINTN i;
737
738 for (i = 0; i < PixelCount; i++) {
739 *DestPlanePtr = *SrcPlanePtr;
740 DestPlanePtr += 4, SrcPlanePtr += 4;
741 }
742}
743
744
745
746
747#define VIDEO(x) (((boot_args*)getBootArgs())->Video.v_ ## x)
748//#define vram VIDEO(baseAddr)
749
750VOID egVramWrite (IN VOID *data, IN UINTN width, IN UINTN Height, IN UINTN PosX, IN UINTN PosY, UINTN BytesPerScanLine)
751{
752
753 UINT8 *vram = (UINT8 *)VIDEO(baseAddr);
754 UINTN depth = (UINTN)VIDEO (depth);
755 UINTN rowBytes = (UINTN)VIDEO (rowBytes);
756 UINTN vHeight = (UINTN)VIDEO (height);
757 UINTN vWidth ;
758
759if (depth == 0x20 && rowBytes == (UINT32)width * BytesPerScanLine)
760memcpy((CHAR8 *)vram, data, rowBytes * vHeight);
761else
762{
763UINT32 r, g, b;
764UINT32 i, j;
765
766 UINT32 x, y;
767 vWidth = (UINTN)VIDEO (width);
768
769 x = MIN(vWidth, width);
770 y = MIN(vHeight, Height);
771
772for (i = PosY; i < y; i++)
773for (j = PosX; j < x; j++)
774{
775b = ((UINT8 *) data)[4*i*width + 4*j];
776g = ((UINT8 *) data)[4*i*width + 4*j + 1];
777r = ((UINT8 *) data)[4*i*width + 4*j + 2];
778switch (depth)
779{
780case 32:
781
782*(UINT32 *)(((UINT8 *)vram)+i* x*BytesPerScanLine + j*4) = (b&0xff) | ((g&0xff)<<8) | ((r&0xff)<<16);
783break;
784case 24:
785 *(UINT32 *)(((UINT8 *)vram)+i*x*BytesPerScanLine + j*3) = ((*(UINT32 *)(((UINT8 *)vram)+i*x*BytesPerScanLine + j*3))&0xff000000)
786| (b&0xff) | ((g&0xff)<<8) | ((r&0xff)<<16);
787break;
788case 16:
789// Somehow 16-bit is always 15-bits really
790//*(uint16_t *)(((uint8_t *)vram)+i*VIDEO (rowBytes) + j*2) = ((b&0xf8)>>3) | ((g&0xfc)<<3) | ((r&0xf8)<<8);
791//break;
792case 15:
793
794*(UINT16 *)(((UINT8 *)vram)+i*x*BytesPerScanLine + j*2) = ((b&0xf8)>>3) | ((g&0xf8)<<2) | ((r&0xf8)<<7);
795break;
796default:
797break;
798}
799}
800}
801}

Archive Download this file

Revision: 2182