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

Archive Download this file

Revision: 2183