swr: [rasterizer core] buckets fixes
[mesa.git] / src / gallium / drivers / swr / rasterizer / core / utils.cpp
1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * @file utils.cpp
24 *
25 * @brief Utilities used by SWR core.
26 *
27 ******************************************************************************/
28 #if defined(_WIN32)
29
30 #if defined(NOMINMAX)
31 // GDI Plus requires non-std min / max macros be defined :(
32 #undef NOMINMAX
33 #endif
34
35 #include<Windows.h>
36 #include <Gdiplus.h>
37 #include <Gdiplusheaders.h>
38 #include <cstdint>
39
40 using namespace Gdiplus;
41
42 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
43 {
44 uint32_t num = 0; // number of image encoders
45 uint32_t size = 0; // size of the image encoder array in bytes
46
47 ImageCodecInfo* pImageCodecInfo = nullptr;
48
49 GetImageEncodersSize(&num, &size);
50 if(size == 0)
51 return -1; // Failure
52
53 pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
54 if(pImageCodecInfo == nullptr)
55 return -1; // Failure
56
57 GetImageEncoders(num, size, pImageCodecInfo);
58
59 for(uint32_t j = 0; j < num; ++j)
60 {
61 if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
62 {
63 *pClsid = pImageCodecInfo[j].Clsid;
64 free(pImageCodecInfo);
65 return j; // Success
66 }
67 }
68
69 free(pImageCodecInfo);
70 return -1; // Failure
71 }
72
73 void SaveImageToPNGFile(
74 const WCHAR *pFilename,
75 void *pBuffer,
76 uint32_t width,
77 uint32_t height,
78 bool broadcastRed = false)
79 {
80 // dump pixels to a png
81 // Initialize GDI+.
82 GdiplusStartupInput gdiplusStartupInput;
83 ULONG_PTR gdiplusToken;
84 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
85
86 Bitmap *bitmap = new Bitmap(width, height);
87 BYTE *pBytes = (BYTE*)pBuffer;
88 const uint32_t bytesPerPixel = (broadcastRed ? 1 : 4);
89 for (uint32_t y = 0; y < height; ++y)
90 for (uint32_t x = 0; x < width; ++x)
91 {
92 uint32_t pixel = 0;
93 if (broadcastRed)
94 {
95 pixel = *(uint8_t*)pBytes;
96 pixel = pixel | (pixel << 8) | (pixel << 16) | 0xFF000000;
97 }
98 else
99 {
100 pixel = *(uint32_t*)pBytes;
101 if (pixel == 0xcdcdcdcd)
102 {
103 pixel = 0xFFFF00FF;
104 }
105 else if (pixel == 0xdddddddd)
106 {
107 pixel = 0x80FF0000;
108 }
109 else
110 {
111 pixel |= 0xFF000000;
112 }
113 }
114
115 Color color(pixel);
116 bitmap->SetPixel(x, y, color);
117 pBytes += bytesPerPixel;
118 }
119
120 // Save image.
121 CLSID pngClsid;
122 GetEncoderClsid(L"image/png", &pngClsid);
123 bitmap->Save(pFilename, &pngClsid, nullptr);
124
125 delete bitmap;
126
127 GdiplusShutdown(gdiplusToken);
128 }
129
130 void OpenBitmapFromFile(
131 const WCHAR *pFilename,
132 void **pBuffer,
133 uint32_t *width,
134 uint32_t *height)
135 {
136 GdiplusStartupInput gdiplusStartupInput;
137 ULONG_PTR gdiplusToken;
138 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
139
140 Bitmap *bitmap = new Bitmap(pFilename);
141
142 *width = bitmap->GetWidth();
143 *height = bitmap->GetHeight();
144 *pBuffer = new BYTE[*width * *height * 4]; // width * height * |RGBA|
145
146 // The folder 'stb_image' contains a PNG open/close module which
147 // is far less painful than this is, yo.
148 Gdiplus::Color clr;
149 for (uint32_t y = 0, idx = 0; y < *height; ++y)
150 {
151 for (uint32_t x = 0; x < *width; ++x, idx += 4)
152 {
153 bitmap->GetPixel(x, *height - y - 1, &clr);
154 ((BYTE*)*pBuffer)[idx + 0] = clr.GetBlue();
155 ((BYTE*)*pBuffer)[idx + 1] = clr.GetGreen();
156 ((BYTE*)*pBuffer)[idx + 2] = clr.GetRed();
157 ((BYTE*)*pBuffer)[idx + 3] = clr.GetAlpha();
158 }
159 }
160
161 delete bitmap;
162 bitmap = 0;
163 }
164 #endif