1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Utility Toolkit Sources
4 // Copyright (C) 2000-2008 by Denton Woods
5 // Last modified: 12/14/2008
6 //
7 // Filename: src-ILUT/src/ilut_win32.c
8 //
9 // Description: Windows functions for images
10 //
11 //-----------------------------------------------------------------------------
12
13
14 #include "ilut_internal.h"
15 #ifdef ILUT_USE_WIN32
16 #include <windows.h>
17 #include <wininet.h>
18
19 // For ilutWinLoadUrl().
20 #ifdef _MSC_VER
21 #pragma comment(lib, "wininet.lib")
22 #endif
23
24
25 #if !_WIN32_WCE && (_WIN32 && __GNUC__)
26 PRINTDLG Pd;
27 #endif//_WIN32_WCE
28
ilutWin32Init()29 ILboolean ilutWin32Init()
30 {
31
32
33 return IL_TRUE;
34 }
35
36
ilutConvertSliceToHBitmap(HDC hDC,ILuint slice)37 ILAPI HBITMAP ILAPIENTRY ilutConvertSliceToHBitmap(HDC hDC, ILuint slice)
38 {
39 ILubyte *Data, *DataBackup;
40 HBITMAP hBitmap = NULL;
41 ILimage *TempImage = NULL;
42 ILuint pad, i, j, k, l, m, n, DepthBackup;
43 ILpal *palImg;
44 ILboolean alloc_buffer;
45
46 //reserve space for palette in every case...
47 ILubyte buff[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)];
48 BITMAPINFO *info = (BITMAPINFO*)buff;
49 RGBQUAD *pal = info->bmiColors;
50
51 ilutCurImage = ilGetCurImage();
52 if (ilutCurImage == NULL) {
53 ilSetError(ILUT_ILLEGAL_OPERATION);
54 return NULL;
55 }
56
57 //check if the image has the wanted slice
58 if (slice < 0 || slice >= ilutCurImage->Depth) {
59 ilSetError(ILUT_INVALID_PARAM);
60 return NULL;
61 }
62
63 // Fool iConvertImage into thinking that the current image has
64 // only one slice, the one we want:
65 DepthBackup = ilutCurImage->Depth;
66 DataBackup = ilutCurImage->Data;
67 ilutCurImage->Depth = 1;
68 ilutCurImage->Data += ilutCurImage->SizeOfPlane*slice;
69
70 if (ilutCurImage->Type != IL_UNSIGNED_BYTE)
71 TempImage = iConvertImage(ilutCurImage, ilutCurImage->Format, IL_UNSIGNED_BYTE);
72 else
73 TempImage = ilutCurImage;
74 if (TempImage == NULL) {
75 goto error;
76 }
77
78 //changed 2003-09-09: use Temp!
79 ilSetCurImage(TempImage);
80
81 hBitmap = CreateCompatibleBitmap(hDC, ilutCurImage->Width, ilutCurImage->Height);
82 if (hBitmap == NULL) {
83 ilSetError(IL_UNKNOWN_ERROR);
84 goto error;
85 }
86
87 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
88 info->bmiHeader.biWidth = TempImage->Width;
89 if (TempImage->Origin == IL_ORIGIN_UPPER_LEFT)
90 info->bmiHeader.biHeight = -(ILint)TempImage->Height;
91 else
92 info->bmiHeader.biHeight = TempImage->Height;
93 info->bmiHeader.biPlanes = 1;
94 info->bmiHeader.biCompression = 0;
95 info->bmiHeader.biSizeImage = 0;
96 info->bmiHeader.biXPelsPerMeter = 0;
97 info->bmiHeader.biYPelsPerMeter = 0;
98 info->bmiHeader.biClrUsed = 0;
99 info->bmiHeader.biClrImportant = 0;
100
101 pad = (4 - TempImage->Bps%4)%4;
102 alloc_buffer = (ILboolean)!(pad == 0 && TempImage->Format != IL_RGB
103 && TempImage->Format != IL_RGBA && TempImage->Format != IL_LUMINANCE_ALPHA);
104 if (!alloc_buffer) {
105 Data = TempImage->Data;
106 }
107 else {
108 ILsizei DataSize = 0;
109 if (TempImage->Format == IL_RGBA) { // Strip alpha during byte swapping for faster upload to GDI.
110 // Recalculate pad, because it changes when bpp changes.
111 pad = (4 - (3 * TempImage->Width) % 4) % 4;
112 DataSize = (TempImage->Width + pad) * TempImage->Height * 3;
113 }
114 // Strip alpha channel from grayscale image.
115 else if (TempImage->Format == IL_LUMINANCE_ALPHA) {
116 // Added 01-09-2009: Recalculate pad.
117 pad = (4 - TempImage->Width % 4) % 4;
118 DataSize = (TempImage->Width + pad) * TempImage->Height;
119 }
120 else {
121 DataSize = (TempImage->Width + pad) * TempImage->Height * TempImage->Bpp;
122 }
123
124 Data = (ILubyte*)ialloc(DataSize);
125 if (Data == NULL) {
126 goto error;
127 }
128
129 if (TempImage->Format == IL_RGB || TempImage->Format == IL_RGBA) {
130 //swap bytes
131 m = (TempImage->Format == IL_RGB)?3:4;
132 k = l = 0;
133 for (j = 0; j < TempImage->Height; j++) {
134 for (i = 0, n = 0; i < 3*TempImage->Width; i += 3, n += m) {
135 Data[l + i] = TempImage->Data[k + n + 2];
136 Data[l + i + 1] = TempImage->Data[k + n + 1];
137 Data[l + i + 2] = TempImage->Data[k + n];
138 }
139
140 k += TempImage->Bps;
141 l += 3*TempImage->Width + pad;
142 }
143 }
144 else if (TempImage->Format == IL_LUMINANCE_ALPHA) {
145 //strip alpha channel
146 //recalculate pad because it included alpha channel info
147 pad = (4 - TempImage->Width%4)%4;
148 k = l = 0;
149 for (j = 0; j < TempImage->Height; j++) {
150 for (i = 0, n = 0; i < TempImage->Width; ++i, n += 2) {
151 Data[l + i] = TempImage->Data[k + n];
152 }
153 k += TempImage->Bps;
154 l += TempImage->Width + pad;
155 }
156 }
157 else
158 for (i = 0; i < TempImage->Height; i++)
159 memcpy(Data + i*(TempImage->Bps + pad), TempImage->Data + i*TempImage->Bps, TempImage->Bps);
160 }
161
162 switch (TempImage->Format)
163 {
164 case IL_LUMINANCE:
165 case IL_LUMINANCE_ALPHA:
166 case IL_COLOUR_INDEX:
167 if (TempImage->Format != IL_COLOUR_INDEX) {
168 //generate greyscale palette
169 for (i = 0; i < 256; i++)
170 pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (ILubyte)i;
171 }
172 else {
173 palImg = iConvertPal(&TempImage->Pal, IL_PAL_BGR32);
174 if (palImg != NULL) {
175 memcpy(pal, palImg->Palette, palImg->PalSize);
176 ilClosePal(palImg);
177 }
178 else {
179 //ilSetError(IL_INVALID_PARAM);
180 // Generate greyscale palette <-- Why is this here?
181 for (i = 0; i < 256; i++)
182 pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (ILubyte)i;
183 }
184 }
185 info->bmiHeader.biBitCount = 8;
186 break;
187
188 case IL_RGB:
189 case IL_BGR:
190 case IL_RGBA: //alpha is removed during byte swapping
191 info->bmiHeader.biBitCount = 24;
192 break;
193
194 case IL_BGRA:
195 info->bmiHeader.biBitCount = 32;
196 break;
197
198 /*default:
199 ilSetError(IL_FORMAT_NOT_SUPPORTED);
200 return hBitmap;*/
201 }
202
203 // Restore original data
204 ilutCurImage->Data = DataBackup;
205 ilutCurImage->Depth = DepthBackup;
206
207 SetDIBits(hDC, hBitmap, 0, ilutCurImage->Height, Data, info, DIB_RGB_COLORS);
208
209 if (alloc_buffer)
210 ifree(Data);
211
212 if (ilutCurImage != TempImage) {
213 ilSetCurImage(ilutCurImage);
214 ilCloseImage(TempImage);
215 }
216
217 return hBitmap;
218
219 error:
220 // Restore original data
221 ilutCurImage->Data = DataBackup;
222 ilutCurImage->Depth = DepthBackup;
223 if (ilutCurImage != TempImage) {
224 ilSetCurImage(ilutCurImage);
225 ilCloseImage(TempImage);
226 }
227 ilSetCurImage(ilutCurImage);
228 if (hBitmap)
229 DeleteObject(hBitmap);
230
231 return NULL;
232 }
233
ilutConvertToHBitmap(HDC hDC)234 HBITMAP ILAPIENTRY ilutConvertToHBitmap(HDC hDC)
235 {
236 return ilutConvertSliceToHBitmap(hDC, 0);
237 }
238
iGetPaddedData(ILimage * Image)239 ILubyte* ILAPIENTRY iGetPaddedData(ILimage *Image)
240 {
241 ILubyte *NewData = NULL, *TempBuff = NULL;
242 ILuint i, CurPos = 0, PadSize;
243 ILubyte *TempData = NULL;
244
245 if (Image == NULL) {
246 ilSetError(ILUT_INVALID_PARAM);
247 return NULL;
248 }
249
250 if (Image->Origin != IL_ORIGIN_LOWER_LEFT) {
251 TempData = iGetFlipped(Image);
252 }
253 else {
254 TempData = Image->Data;
255 }
256
257 if (Image->Format == IL_RGB || Image->Format == IL_RGBA) {
258 TempBuff = (ILubyte*)ialloc(Image->SizeOfData);
259
260 if (TempBuff == NULL) {
261 return NULL;
262 }
263 // Swap red and blue.
264 for (i = 0; i < Image->SizeOfData; i += Image->Bpp) {
265 TempBuff[i] = TempData[i+2];
266 TempBuff[i+1] = TempData[i+1];
267 TempBuff[i+2] = TempData[i];
268 // Copy the alpha channel if present.
269 if (Image->Bpp == 4)
270 TempBuff[i+3] = TempData[i+3];
271 }
272 }
273 else {
274 TempBuff = TempData;
275 }
276
277 PadSize = (4 - (Image->Bps % 4)) % 4;
278 NewData = (ILubyte*)ialloc((Image->Width + PadSize) * Image->Height * Image->Bpp);
279 if (NewData == NULL) {
280 return NULL;
281 }
282
283 for (i = 0; i < Image->Height; i++) {
284 memcpy(NewData + CurPos, TempBuff + Image->Bps * i, Image->Bps);
285 CurPos += Image->Bps;
286 memset(NewData + CurPos, 0, PadSize);
287 CurPos += PadSize;
288 }
289
290 if (TempData != TempBuff && TempData != Image->Data)
291 ifree(TempData);
292 if (TempBuff != Image->Data)
293 ifree(TempBuff);
294
295 return NewData;
296 }
297
298
299
ilutFreePaddedData(ILubyte * Data)300 void ILAPIENTRY ilutFreePaddedData(ILubyte *Data)
301 {
302 ifree(Data);
303 return;
304 }
305
306
307 // DirectX/GDI insists that all scanlines end on a dword boundary. =(
ilutGetPaddedData()308 ILubyte* ILAPIENTRY ilutGetPaddedData()
309 {
310 return iGetPaddedData(ilGetCurImage());
311 }
312
313
314 // @TODO: Figure how to mess with multiple bpc's!
ilutGetBmpInfo(BITMAPINFO * Info)315 void ILAPIENTRY ilutGetBmpInfo(BITMAPINFO *Info)
316 {
317 ILuint NewBps, Padding;
318
319 ilutCurImage = ilGetCurImage();
320 if (ilutCurImage == NULL) {
321 ilSetError(ILUT_ILLEGAL_OPERATION);
322 return;
323 }
324
325 Padding = (4 - (ilutCurImage->Bps % 4)) % 4;
326 NewBps = ilutCurImage->Bps/* + Padding*/;
327
328 Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
329 Info->bmiHeader.biWidth = ilutCurImage->Width;
330 Info->bmiHeader.biHeight = ilutCurImage->Height;
331 Info->bmiHeader.biPlanes = 1;
332 Info->bmiHeader.biBitCount = ilutCurImage->Bpp << 3;
333 Info->bmiHeader.biCompression = BI_RGB;
334 Info->bmiHeader.biSizeImage = NewBps * ilutCurImage->Height;
335 Info->bmiHeader.biXPelsPerMeter = 0;
336 Info->bmiHeader.biYPelsPerMeter = 0;
337 Info->bmiHeader.biClrUsed = ilutCurImage->Bpp == 1 ? 255 : 0;
338 if (Info->bmiHeader.biClrUsed < 24)
339 Info->bmiHeader.biClrImportant = Info->bmiHeader.biClrUsed;
340 else
341 Info->bmiHeader.biClrImportant = 0;
342
343 return;
344 }
345
346
347 //! Just a convenience function.
ilutWinLoadImage(ILstring FileName,HDC hDC)348 HBITMAP ILAPIENTRY ilutWinLoadImage(ILstring FileName, HDC hDC)
349 {
350 HBITMAP Bitmap;
351
352 iBindImageTemp();
353 if (!ilLoadImage(FileName))
354 return 0;
355
356 Bitmap = ilutConvertToHBitmap(hDC);
357
358 return Bitmap;
359 }
360
361
362 #ifndef _WIN32_WCE
ilutWinSaveImage(ILstring FileName,HBITMAP Bitmap)363 ILboolean ILAPIENTRY ilutWinSaveImage(ILstring FileName, HBITMAP Bitmap)
364 {
365 ILuint CurName;
366 ILboolean Saved;
367
368 CurName = ilGetCurName();
369
370 iBindImageTemp();
371
372 if (!ilutSetHBitmap(Bitmap)) {
373 ilBindImage(CurName);
374 return IL_FALSE;
375 }
376
377 Saved = ilSaveImage(FileName);
378 ilBindImage(CurName);
379
380 return Saved;
381 }
382 #endif//_WIN32_WCE
383
384
385 // @TODO: Just create a copy of the palette!
386 // Credit for this goes to the OpenGL SuperBible.
ilutGetHPal()387 HPALETTE ILAPIENTRY ilutGetHPal()
388 {
389 HPALETTE Palette;
390 LOGPALETTE *LogPal;
391 ILuint NumEntries, i;
392 ILenum CurPalType;
393
394 ilutCurImage = ilGetCurImage();
395 if (ilutCurImage == NULL) {
396 ilSetError(ILUT_ILLEGAL_OPERATION);
397 return NULL;
398 }
399
400 if (!ilutCurImage->Pal.Palette || !ilutCurImage->Pal.PalSize || ilutCurImage->Pal.PalType == IL_PAL_NONE) {
401 //ilSetError(ILUT_ILLEGAL_OPERATION);
402 return NULL;
403 }
404
405 CurPalType = ilutCurImage->Pal.PalType;
406 if (!ilConvertPal(IL_PAL_RGB24)) {
407 return NULL; // ilConvertPal already sets the error
408 }
409 NumEntries = ilutCurImage->Pal.PalSize / 3;
410
411 LogPal = (LOGPALETTE*)ialloc(sizeof(LOGPALETTE) + NumEntries * sizeof(PALETTEENTRY));
412 if (!LogPal) {
413 return NULL;
414 }
415
416 LogPal->palVersion = 0x300;
417 LogPal->palNumEntries = (WORD)NumEntries;
418
419 for (i = 0; i < NumEntries; i++) {
420 LogPal->palPalEntry[i].peRed = ilutCurImage->Pal.Palette[i * 3];
421 LogPal->palPalEntry[i].peGreen = ilutCurImage->Pal.Palette[i * 3 + 1];
422 LogPal->palPalEntry[i].peBlue = ilutCurImage->Pal.Palette[i * 3 + 2];
423 LogPal->palPalEntry[i].peFlags = 0;
424 }
425
426 Palette = CreatePalette(LogPal);
427 ifree(LogPal);
428
429 ilConvertPal(CurPalType); // Should we check the return value?
430
431 return Palette;
432 }
433
434
ilutSetHBitmap(HBITMAP Bitmap)435 ILboolean ILAPIENTRY ilutSetHBitmap(HBITMAP Bitmap)
436 {
437 #ifndef _WIN32_WCE
438 BITMAPINFO Info[2];
439 HWND hWnd;
440 HDC hDC;
441 ILubyte *Buffer1 = NULL, *Buffer2 = NULL;
442 ILuint i, j, PadSize, Bps;
443
444 ilutCurImage = ilGetCurImage();
445 if (ilutCurImage == NULL) {
446 ilSetError(ILUT_ILLEGAL_OPERATION);
447 return IL_FALSE;
448 }
449
450 hWnd = GetForegroundWindow();
451 hDC = GetDC(hWnd);
452
453 // Query the dimensions
454 memset(&Info, 0, sizeof(BITMAPINFO));
455 Info[0].bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
456 GetDIBits(hDC, Bitmap, 0, 0, NULL, Info, DIB_RGB_COLORS);
457
458 // @TODO: Implement this shitz0rz!
459 if (Info[0].bmiHeader.biBitCount < 24) {
460 ReleaseDC(hWnd, hDC); //added 20040527
461 return IL_FALSE;
462 }
463
464 Buffer1 = (ILubyte*)ialloc(Info[0].bmiHeader.biSizeImage);
465 Buffer2 = (ILubyte*)ialloc(Info[0].bmiHeader.biSizeImage);
466 if (Buffer1 == NULL || Buffer2 == NULL) {
467 ReleaseDC(hWnd, hDC); //added 20040527
468 ifree(Buffer1);
469 ifree(Buffer2);
470 return IL_FALSE;
471 }
472
473 //GetBitmapBits
474 GetDIBits(hDC, Bitmap, 0, Info[0].bmiHeader.biHeight, Buffer1, Info, DIB_RGB_COLORS);
475
476 Bps = Info[0].bmiHeader.biWidth * (Info[0].bmiHeader.biBitCount >> 3);
477 PadSize = (4 - (Bps % 4)) % 4;
478
479 // Remove the padding.
480 for (i = 0, j = 0; i < Info[0].bmiHeader.biSizeImage; i += Bps + PadSize, j += Bps) {
481 memcpy(Buffer2 + j, Buffer1 + i, Bps);
482 }
483
484 if (Info[0].bmiHeader.biBitCount == 24) {
485 ilTexImage(Info[0].bmiHeader.biWidth, Info[0].bmiHeader.biHeight, 1,
486 (ILubyte)(Info[0].bmiHeader.biBitCount >> 3), IL_BGR, IL_UNSIGNED_BYTE, Buffer2);
487 }
488 else if (Info[0].bmiHeader.biBitCount == 32) {
489 ilTexImage(Info[0].bmiHeader.biWidth, Info[0].bmiHeader.biHeight, 1,
490 (ILubyte)(Info[0].bmiHeader.biBitCount >> 3), IL_BGRA, IL_UNSIGNED_BYTE, Buffer2);
491 }
492 ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
493
494 ReleaseDC(hWnd, hDC); //added 20040527
495 ifree(Buffer1);
496 ifree(Buffer2);
497
498 #endif//_WIN32_WCE
499
500 return IL_TRUE;
501 }
502
503
ilutSetHPal(HPALETTE Pal)504 ILboolean ILAPIENTRY ilutSetHPal(HPALETTE Pal)
505 {
506 LPPALETTEENTRY PalEntries;
507 ILuint NumEntries, i;
508 ILubyte *TempPal;
509
510 ilutCurImage = ilGetCurImage();
511 if (ilutCurImage == NULL) {
512 ilSetError(ILUT_ILLEGAL_OPERATION);
513 return IL_FALSE;
514 }
515
516 NumEntries = GetPaletteEntries(Pal, 0, 0, NULL);
517 if (NumEntries == 0)
518 return IL_TRUE; // @TODO: Determine if correct...
519
520 PalEntries = (LPPALETTEENTRY)ialloc(NumEntries * sizeof(PALETTEENTRY));
521 if (PalEntries == NULL) {
522 return IL_FALSE;
523 }
524
525 NumEntries = GetPaletteEntries(Pal, 0, NumEntries, PalEntries);
526
527 TempPal = (ILubyte*)ialloc(NumEntries * 3);
528 if (TempPal == NULL) {
529 ifree(PalEntries);
530 return IL_FALSE;
531 }
532 if (ilutCurImage->Pal.Palette)
533 ifree(ilutCurImage->Pal.Palette);
534 ilutCurImage->Pal.Palette = TempPal;
535 ilutCurImage->Pal.PalSize = NumEntries * 3;
536 ilutCurImage->Pal.PalType = IL_PAL_RGB24;
537
538 for (i = 0; i < NumEntries; i++) {
539 *TempPal++ = PalEntries[i].peRed;
540 *TempPal++ = PalEntries[i].peGreen;
541 *TempPal++ = PalEntries[i].peBlue;
542 }
543
544 ifree(PalEntries);
545
546 return IL_TRUE;
547 }
548
549
ilutSetWinClipboard()550 ILboolean ILAPIENTRY ilutSetWinClipboard()
551 {
552 HBITMAP Bitmap;
553 HANDLE Handle;
554 HWND hWnd;
555 HDC hDC;
556 ILimage *TempImage, *CurImage;
557
558 ilutCurImage = ilGetCurImage();
559 if (ilutCurImage == NULL) {
560 ilSetError(ILUT_ILLEGAL_OPERATION);
561 return IL_FALSE;
562 }
563
564 if (ilutCurImage->Format != IL_BGR || ilutCurImage->Bps > 1) {
565 TempImage = iConvertImage(ilutCurImage, IL_BGR, IL_UNSIGNED_BYTE);
566 if (TempImage == NULL)
567 return IL_FALSE;
568 }
569 else
570 TempImage = ilutCurImage;
571
572 CurImage = ilutCurImage;
573 ilSetCurImage(TempImage);
574
575 hWnd = GetForegroundWindow();
576 hDC = GetDC(hWnd);
577
578 if (!OpenClipboard(NULL)) {
579 if (TempImage != ilutCurImage)
580 ilCloseImage(TempImage);
581 ilSetCurImage(CurImage);
582 ilSetError(ILUT_ILLEGAL_OPERATION); // Dunno if this is the correct error.
583 ReleaseDC(hWnd, hDC); //added 20040604
584 if (TempImage != ilutCurImage)
585 ilCloseImage(TempImage);
586 ilSetCurImage(CurImage);
587 return IL_FALSE;
588 }
589
590 //note that this is not the best method to put an image into the
591 //clipboard, CF_DIB is much better because HBITMAPS are device-dependent.
592 //TODO: eventually change that if there is a need
593 Bitmap = ilutConvertToHBitmap(hDC);
594 ReleaseDC(hWnd, hDC); //added 20040604
595
596 EmptyClipboard();
597 Handle = SetClipboardData(CF_BITMAP, Bitmap);
598
599 CloseClipboard();
600
601 //DeleteObject(Bitmap); // Needed? No! Clipboard takes care of image.
602
603 if (TempImage != ilutCurImage)
604 ilCloseImage(TempImage);
605 ilSetCurImage(CurImage);
606
607 return IL_TRUE;
608 }
609
610
ilutGetWinClipboard()611 ILboolean ILAPIENTRY ilutGetWinClipboard()
612 {
613 //HBITMAP Bitmap;
614 HWND hWnd;
615 HGLOBAL hGlobal;
616 PTSTR pGlobal, data;
617 BITMAPFILEHEADER *BmpHeader;
618 BITMAPINFOHEADER *InfoHeader;
619 SIZE_T Size;
620
621 ilutCurImage = ilGetCurImage();
622 if (ilutCurImage == NULL) {
623 ilSetError(ILUT_ILLEGAL_OPERATION);
624 return IL_FALSE;
625 }
626
627 if (IsClipboardFormatAvailable(CF_DIB)) {
628 hWnd = GetForegroundWindow();
629
630 if (!OpenClipboard(hWnd)) {
631 ilSetError(ILUT_ILLEGAL_OPERATION); // Dunno if this is the correct error.
632 return IL_FALSE;
633 }
634
635 hGlobal = GetClipboardData(CF_DIB);
636 if (!hGlobal) {
637 CloseClipboard();
638 return IL_FALSE; // No error?
639 }
640
641 //copy DIB to buffer because windows delivers it without the
642 //BITMAPFILEHEADER that DevIL needs to load the image
643 Size = GlobalSize(hGlobal);
644 //@TODO: Size should never be larger than an ILuint?
645 data = (PTSTR)ialloc((ILuint)Size + sizeof(BITMAPFILEHEADER));
646 pGlobal = (PTSTR)GlobalLock(hGlobal);
647 if (!pGlobal || !data) {
648 ifree(data);
649 CloseClipboard();
650 return IL_FALSE; // No error?
651 }
652 memcpy(data + sizeof(BITMAPFILEHEADER), pGlobal, Size);
653 GlobalUnlock(hGlobal);
654 CloseClipboard();
655
656 //create BITMAPFILEHEADER
657 InfoHeader = (BITMAPINFOHEADER*)(data + sizeof(BITMAPFILEHEADER));
658 BmpHeader = (BITMAPFILEHEADER*)data;
659 BmpHeader->bfType = 'B' | ('M' << 8);
660 //@TODO: Again, could it ever be larger than an unsigned integer (DWORD)?
661 BmpHeader->bfSize = (DWORD)Size + sizeof(BITMAPFILEHEADER);
662 BmpHeader->bfReserved1 = BmpHeader->bfReserved2 = 0;
663 BmpHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + InfoHeader->biSize + InfoHeader->biClrUsed*4;
664 if (InfoHeader->biCompression == BI_BITFIELDS)
665 BmpHeader->bfOffBits += 12;
666
667 return ilLoadL(IL_BMP, data, BmpHeader->bfSize);
668 }
669 /*
670 //this is not required becaus CF_BITMAP is converted to CF_DIB automatically
671 //when needed. CF_DIB suffices.
672 else if (IsClipboardFormatAvailable(CF_BITMAP)) {
673 hWnd = GetForegroundWindow();
674
675 if (!OpenClipboard(hWnd)) {
676 ilSetError(ILUT_ILLEGAL_OPERATION); // Dunno if this is the correct error.
677 return IL_FALSE;
678 }
679
680 Bitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
681 if (!Bitmap) {
682 CloseClipboard();
683 return IL_FALSE; // No error?
684 }
685
686 if (!ilutSetHBitmap(Bitmap)) {
687 CloseClipboard();
688 return IL_FALSE;
689 }
690
691 CloseClipboard();
692 }*/
693
694 //no data in clipboard
695 ilSetError(ILUT_ILLEGAL_OPERATION);
696 return IL_FALSE;
697 }
698
699
ilutWinPrint(ILuint XPos,ILuint YPos,ILuint Width,ILuint Height,HDC hDC)700 ILboolean ILAPIENTRY ilutWinPrint(ILuint XPos, ILuint YPos, ILuint Width, ILuint Height, HDC hDC)
701 {
702 #if !defined(_WIN32_WCE) && !(defined(_WIN32) && defined(__GNUC__))
703 PRINTDLG Pd;
704 DOCINFO Di;
705 HBITMAP Bitmap, hReplaced;
706 HDC hMemDC;
707
708 ilutCurImage = ilGetCurImage();
709 if (ilutCurImage == NULL) {
710 ilSetError(ILUT_ILLEGAL_OPERATION);
711 return IL_FALSE;
712 }
713
714 //@TODO: Needs error checking!
715 hMemDC = CreateCompatibleDC(hDC);
716 Bitmap = ilutConvertToHBitmap(hDC);
717 hReplaced = (HBITMAP)SelectObject(hMemDC, Bitmap);
718
719 memset(&Pd, 0, sizeof(PRINTDLG));
720 Pd.lStructSize = sizeof(PRINTDLG);
721 Pd.hwndOwner = GetForegroundWindow();
722 Pd.Flags = PD_RETURNDC;
723 Pd.nCopies = 1;
724 Pd.nFromPage = 0xFFFF;
725 Pd.nToPage = 0xFFFF;
726 Pd.nMinPage = 1;
727 Pd.nMaxPage = 0xFFFF;
728
729 if (!PrintDlg(&Pd))
730 return (0L);
731
732 Di.cbSize = sizeof(DOCINFO);
733 Di.lpszDocName = IL_TEXT("DevIL Print Job");
734 Di.lpszOutput = NULL;
735 Di.lpszDatatype = NULL;
736 Di.fwType = 0;
737
738 StartDoc(Pd.hDC, &Di);
739 StartPage(Pd.hDC);
740
741 StretchBlt(Pd.hDC, XPos, YPos, Width, Height, hMemDC, 0, 0, ilutCurImage->Width, ilutCurImage->Height, SRCCOPY);
742
743 EndPage(Pd.hDC);
744 EndDoc(Pd.hDC);
745 DeleteObject(Bitmap);
746 DeleteObject(hReplaced);
747 DeleteDC(Pd.hDC);
748
749 #endif
750
751 return IL_TRUE;
752 }
753
754
ilutLoadResource(HINSTANCE hInst,ILint ID,ILstring ResourceType,ILenum Type)755 ILboolean ILAPIENTRY ilutLoadResource(HINSTANCE hInst, ILint ID, ILstring ResourceType, ILenum Type)
756 {
757 HRSRC Resource = (HRSRC)LoadResource(hInst, FindResource(hInst, MAKEINTRESOURCE(ID), ResourceType));
758 ILubyte *Data = (ILubyte*)LockResource(Resource);
759
760 return ilLoadL(Type, Data, SizeofResource(hInst, FindResource(hInst, MAKEINTRESOURCE(ID), ResourceType)));
761 }
762
763
764 #if !defined(_WIN32_WCE) && !(defined(_WIN32) && defined(__GNUC__))
765 #define BUFFSIZE 8192 // Change to suit the efficiency.
ilutWinLoadUrl(ILstring Url)766 ILboolean ILAPIENTRY ilutWinLoadUrl(ILstring Url)
767 {
768 HINTERNET Handle, UrlHandle;
769 DWORD BytesRead = 0, Context = 1;
770 ILubyte Buff[BUFFSIZE], *Buffer, *TempBuff;
771 ILuint BufferSize = 0, i;
772 ILboolean Is404 = IL_TRUE;
773 char Buffer404[] = { '<', 'h', 't', 'm', 'l', '>' };
774
775 Buffer = (ILubyte*)ialloc(0);
776 if (Buffer == NULL) {
777 return IL_FALSE;
778 }
779
780 Handle = InternetOpen(IL_TEXT("Developer's Image Library"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
781 if (Handle == NULL) {
782 ifree(Buffer);
783 ilSetError(ILUT_COULD_NOT_OPEN_FILE);
784 return IL_FALSE;
785 }
786
787 // Try again if fails the first time, loading only from the cache.
788 UrlHandle = InternetOpenUrl(Handle, Url, NULL, 0, 0, Context);
789 if (UrlHandle == NULL) {
790 InternetCloseHandle(Handle);
791 Handle = InternetOpen(IL_TEXT("Developer's Image Library"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_FROM_CACHE);
792 if (Handle == NULL) {
793 ifree(Buffer);
794 ilSetError(ILUT_COULD_NOT_OPEN_FILE);
795 return IL_FALSE;
796 }
797 UrlHandle = InternetOpenUrl(Handle, Url, NULL, 0, 0, Context);
798 if (UrlHandle == NULL) {
799 ifree(Buffer);
800 InternetCloseHandle(Handle);
801 ilSetError(ILUT_COULD_NOT_OPEN_FILE);
802 return IL_FALSE;
803 }
804 }
805
806 do {
807 if (!InternetReadFile(UrlHandle, Buff, BUFFSIZE, &BytesRead)) {
808 InternetCloseHandle(UrlHandle);
809 InternetCloseHandle(Handle);
810 ifree(Buffer);
811 ilSetError(ILUT_COULD_NOT_OPEN_FILE);
812 return IL_FALSE;
813 }
814
815 TempBuff = (ILubyte*)ialloc(BufferSize + BytesRead);
816 if (TempBuff == NULL) {
817 ifree(Buffer);
818 return IL_FALSE;
819 }
820
821 memcpy(TempBuff, Buffer, BufferSize);
822 memcpy(TempBuff + BufferSize, Buff, BytesRead);
823 ifree(Buffer);
824 Buffer = TempBuff;
825
826 BufferSize += BytesRead;
827 } while (BytesRead > 0);
828
829 InternetCloseHandle(UrlHandle);
830 InternetCloseHandle(Handle);
831
832 // If the image does not exist, the server usually returns a 404 HTML page.
833 for (i = 0; i < sizeof(Buffer404) && i < BufferSize; i++) {
834 if (tolower(Buffer[i]) != Buffer404[i]) {
835 Is404 = IL_FALSE;
836 break;
837 }
838 }
839
840 if (!Is404) {
841 if (!ilLoadL(ilTypeFromExt(Url), Buffer, BufferSize)) {
842 if (!ilLoadL(IL_TYPE_UNKNOWN, Buffer, BufferSize)) {
843 ifree(Buffer);
844 return IL_FALSE;
845 }
846 }
847 }
848
849 ifree(Buffer);
850
851 return IL_TRUE;
852 }
853 #endif
854
855
856 #endif//ILUT_USE_WIN32
857