ReactOS  0.4.14-dev-384-g5b37caa
icm.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Win32k Subsystem
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: win32ss/gdi/ntgdi/icm.c
5  * PURPOSE: Icm functions
6  * PROGRAMMERS: ...
7  */
8 
9 #include <win32k.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 HCOLORSPACE hStockColorSpace = NULL;
15 
16 
17 HCOLORSPACE
21 {
22  PCOLORSPACE pCS;
23  HCOLORSPACE hCS;
24 
26  if (pCS == NULL) return NULL;
27 
28  hCS = pCS->BaseObject.hHmgr;
29 
30  pCS->lcsColorSpace = pLogColorSpace->lcsColorSpace;
31  pCS->dwFlags = pLogColorSpace->dwFlags;
32 
34  return hCS;
35 }
36 
37 BOOL
40  HCOLORSPACE hColorSpace)
41 {
42  BOOL Ret = FALSE;
43 
44  if ((hColorSpace != hStockColorSpace) &&
46  {
47  Ret = GreDeleteObject(hColorSpace);
49  }
50 
51  return Ret;
52 }
53 
54 HANDLE
58 {
59  LOGCOLORSPACEEXW Safelcs;
61 
62  _SEH2_TRY
63  {
65  RtlCopyMemory(&Safelcs, pLogColorSpace, sizeof(LOGCOLORSPACEEXW));
66  }
68  {
70  }
71  _SEH2_END;
72 
73  if (!NT_SUCCESS(Status))
74  {
76  return NULL;
77  }
78 
79  return IntGdiCreateColorSpace(&Safelcs);
80 }
81 
82 BOOL
85  IN HANDLE hColorSpace)
86 {
87  return IntGdiDeleteColorSpace(hColorSpace);
88 }
89 
90 BOOL
93 {
94  PPDEVOBJ pGDev = (PPDEVOBJ) hPDev;
95  int i;
96 
97  if (!(pGDev->flFlags & PDEV_DISPLAY)) return FALSE;
98 
99  if ((pGDev->devinfo.iDitherFormat == BMF_8BPP) ||
100  (pGDev->devinfo.iDitherFormat == BMF_16BPP) ||
101  (pGDev->devinfo.iDitherFormat == BMF_24BPP) ||
102  (pGDev->devinfo.iDitherFormat == BMF_32BPP))
103  {
104  if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
105  {
106  RtlCopyMemory(Ramp, pGDev->pvGammaRamp, sizeof(GAMMARAMP));
107  }
108  else
109  {
110  // Generate the 256-colors array
111  for (i = 0; i < 256; i++ )
112  {
113  int NewValue = i * 256;
114 
115  Ramp->Red[i] = Ramp->Green[i] = Ramp->Blue[i] = ((WORD)NewValue);
116  }
117  }
118  return TRUE;
119  }
120 
121  return FALSE;
122 }
123 
124 BOOL
125 APIENTRY
127  HDC hDC,
128  LPVOID Ramp)
129 {
130  BOOL Ret;
131  PDC dc;
133  PGAMMARAMP SafeRamp;
134 
135  if (!Ramp) return FALSE;
136 
137  dc = DC_LockDc(hDC);
138  if (!dc)
139  {
141  return FALSE;
142  }
143 
144  SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), GDITAG_ICM);
145  if (!SafeRamp)
146  {
147  DC_UnlockDc(dc);
149  return FALSE;
150  }
151 
152  Ret = IntGetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp);
153  if (!Ret)
154  {
155  DC_UnlockDc(dc);
156  ExFreePoolWithTag(SafeRamp, GDITAG_ICM);
157  return Ret;
158  }
159 
160  _SEH2_TRY
161  {
162  ProbeForWrite(Ramp, sizeof(GAMMARAMP), 1);
163  RtlCopyMemory(Ramp, SafeRamp, sizeof(GAMMARAMP));
164  }
166  {
168  }
169  _SEH2_END;
170 
171  DC_UnlockDc(dc);
172  ExFreePoolWithTag(SafeRamp, GDITAG_ICM);
173 
174  if (!NT_SUCCESS(Status))
175  {
177  return FALSE;
178  }
179  return Ret;
180 }
181 
182 BOOL
183 APIENTRY
185  IN HCOLORSPACE hColorSpace)
186 {
187  PDC pDC;
188  PDC_ATTR pdcattr;
189  PCOLORSPACE pCS;
190 
191  pDC = DC_LockDc(hdc);
192  if (!pDC)
193  {
195  return FALSE;
196  }
197  pdcattr = pDC->pdcattr;
198 
199  if (pdcattr->hColorSpace == hColorSpace)
200  {
201  DC_UnlockDc(pDC);
202  return TRUE;
203  }
204 
205  pCS = COLORSPACEOBJ_LockCS(hColorSpace);
206  if (!pCS)
207  {
209  return FALSE;
210  }
211 
212  if (pDC->dclevel.pColorSpace)
213  {
214  GDIOBJ_vDereferenceObject((POBJ) pDC->dclevel.pColorSpace);
215  }
216 
217  pDC->dclevel.pColorSpace = pCS;
218  pdcattr->hColorSpace = hColorSpace;
219 
221  DC_UnlockDc(pDC);
222  return TRUE;
223 }
224 
225 BOOL
226 FASTCALL
228 {
229  BOOL Ret = FALSE;
230  PPALETTE palGDI;
231  PALOBJ *palPtr;
232  PPDEVOBJ pGDev = (PPDEVOBJ)hPDev;
233 
234  if ((pGDev->devinfo.iDitherFormat == BMF_8BPP) ||
235  (pGDev->devinfo.iDitherFormat == BMF_16BPP) ||
236  (pGDev->devinfo.iDitherFormat == BMF_24BPP) ||
237  (pGDev->devinfo.iDitherFormat == BMF_32BPP))
238  {
240  return pGDev->DriverFunctions.IcmSetDeviceGammaRamp( pGDev->dhpdev,
242  pGDev->pvGammaRamp);
243 
244  if ((pGDev->devinfo.iDitherFormat != BMF_8BPP) ||
245  !(pGDev->gdiinfo.flRaster & RC_PALETTE)) return FALSE;
246 
247  if (!(pGDev->flFlags & PDEV_GAMMARAMP_TABLE)) return FALSE;
248 
250  if(!palGDI) return FALSE;
251  palPtr = (PALOBJ*) palGDI;
252 
253  if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
254  palGDI->flFlags |= PAL_GAMMACORRECTION;
255  else
256  palGDI->flFlags &= ~PAL_GAMMACORRECTION;
257 
258  if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook
259  {
260  // BMF_8BPP only!
261  // PALOBJ_cGetColors check mode flags and update Gamma Correction.
262  // Set the HDEV to pal and go.
263  palGDI->hPDev = hPDev;
264  Ret = pGDev->DriverFunctions.SetPalette(pGDev->dhpdev,
265  palPtr,
266  0,
267  0,
268  palGDI->NumColors);
269  }
271  return Ret;
272  }
273  else
274  return FALSE;
275 }
276 
277 //
278 // ICM registry subkey sets internal brightness range, gamma range is 128 or
279 // 256 when icm is init.
280 INT IcmGammaRangeSet = 128; // <- Make it global
281 
282 BOOL
283 FASTCALL
285 {
286  WORD IcmGR, i, R, G, B;
287  BOOL Ret = FALSE, TstPeak;
288  PPDEVOBJ pGDev = (PPDEVOBJ) hPDev;
289 
290  if (!hPDev) return FALSE;
291 
292  if (!(pGDev->flFlags & PDEV_DISPLAY )) return FALSE;
293 
294  if ((pGDev->devinfo.iDitherFormat == BMF_8BPP) ||
295  (pGDev->devinfo.iDitherFormat == BMF_16BPP) ||
296  (pGDev->devinfo.iDitherFormat == BMF_24BPP) ||
297  (pGDev->devinfo.iDitherFormat == BMF_32BPP))
298  {
300  {
301  // No driver support
303  {
304  // Driver does not support Gamma Ramp, so test to see we
305  // have BMF_8BPP only and palette operation support.
306  if ((pGDev->devinfo.iDitherFormat != BMF_8BPP) ||
307  !(pGDev->gdiinfo.flRaster & RC_PALETTE)) return FALSE;
308  }
309  }
310 
311  if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
312  {
313  if (RtlCompareMemory(pGDev->pvGammaRamp, Ramp, sizeof(GAMMARAMP)) ==
314  sizeof(GAMMARAMP)) return TRUE;
315  }
316 
317  // Verify Ramp is inside range.
318  IcmGR = -IcmGammaRangeSet;
319  TstPeak = (Test == FALSE);
320  for (i = 0; i < 256; i++)
321  {
322  R = Ramp->Red[i] / 256;
323  G = Ramp->Green[i] / 256;
324  B = Ramp->Blue[i] / 256;
325 
326  if (R >= IcmGR)
327  {
328  if (R <= IcmGammaRangeSet + i)
329  {
330  if ((G >= IcmGR) &&
331  (G <= IcmGammaRangeSet + i) &&
332  (B >= IcmGR) &&
333  (B <= IcmGammaRangeSet + i) ) continue;
334  }
335  }
336 
337  if (Test) return Ret; // Don't set and return.
338 
339  // No test override, check max range
340  if (TstPeak)
341  {
342  if ((R != (IcmGR * 256)) ||
343  (G != (IcmGR * 256)) ||
344  (B != (IcmGR * 256)) ) TstPeak = FALSE; // W/i range.
345  }
346  }
347  // ReactOS allocates a ramp even if it is 8BPP and Palette only.
348  // This way we have a record of the change in memory.
349  if (!pGDev->pvGammaRamp && !(pGDev->flFlags & PDEV_GAMMARAMP_TABLE))
350  {
351  // If the above is true and we have nothing allocated, create it.
353  pGDev->flFlags |= PDEV_GAMMARAMP_TABLE;
354  }
355 
356  if (pGDev->pvGammaRamp)
357  RtlCopyMemory(pGDev->pvGammaRamp, Ramp, sizeof(GAMMARAMP));
358 
359  Ret = UpdateDeviceGammaRamp(hPDev);
360  }
361 
362  return Ret;
363 }
364 
365 BOOL
366 APIENTRY
368  HDC hDC,
369  LPVOID Ramp)
370 {
371  BOOL Ret;
372  PDC dc;
374  PGAMMARAMP SafeRamp;
375  if (!Ramp) return FALSE;
376 
377  dc = DC_LockDc(hDC);
378  if (!dc)
379  {
381  return FALSE;
382  }
383 
384  SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), GDITAG_ICM);
385  if (!SafeRamp)
386  {
387  DC_UnlockDc(dc);
389  return FALSE;
390  }
391  _SEH2_TRY
392  {
393  ProbeForRead(Ramp, sizeof(GAMMARAMP), 1);
394  RtlCopyMemory(SafeRamp, Ramp, sizeof(GAMMARAMP));
395  }
397  {
399  }
400  _SEH2_END;
401 
402  if (!NT_SUCCESS(Status))
403  {
404  DC_UnlockDc(dc);
405  ExFreePoolWithTag(SafeRamp, GDITAG_ICM);
407  return FALSE;
408  }
409 
410  Ret = IntSetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp, TRUE);
411  DC_UnlockDc(dc);
412  ExFreePoolWithTag(SafeRamp, GDITAG_ICM);
413  return Ret;
414 }
415 
416 INT
417 APIENTRY
419  ULONG nCommand,
420  ULONG EnableICM) // ulMode
421 {
422  /* FIXME: This should be coded someday */
423  if (EnableICM == ICM_OFF)
424  {
425  return ICM_OFF;
426  }
427  if (EnableICM == ICM_ON)
428  {
429  return 0;
430  }
431  if (EnableICM == ICM_QUERY)
432  {
433  return ICM_OFF;
434  }
435 
436  return 0;
437 }
438 
439 /* EOF */
DHPDEV dhpdev
Definition: pdevobj.h:121
#define BMF_24BPP
Definition: winddi.h:359
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define IN
Definition: typedefs.h:38
#define R(b, x)
Definition: sha2.c:134
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1155
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define BMF_32BPP
Definition: winddi.h:360
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
WORD Green[256]
Definition: winddi.h:776
GDIINFO gdiinfo
Definition: pdevobj.h:124
WORD Red[256]
Definition: winddi.h:775
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
LONG NTSTATUS
Definition: precomp.h:26
static HDC
Definition: imagelist.c:92
HCOLORSPACE hColorSpace
Definition: ntgdihdl.h:323
HCOLORSPACE FASTCALL IntGdiCreateColorSpace(PLOGCOLORSPACEEXW pLogColorSpace)
Definition: icm.c:19
INT IcmGammaRangeSet
Definition: icm.c:280
LOGCOLORSPACEW lcsColorSpace
Definition: color.h:12
VOID NTAPI GDIOBJ_vDereferenceObject(POBJ pobj)
Definition: gdiobj.c:628
HDC dc
Definition: cylfrac.c:34
BOOL FASTCALL IntGdiDeleteColorSpace(HCOLORSPACE hColorSpace)
Definition: icm.c:39
BOOL FASTCALL IntSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp, BOOL Test)
Definition: icm.c:284
PVOID pvGammaRamp
Definition: pdevobj.h:108
#define FASTCALL
Definition: nt_native.h:50
BOOL FASTCALL UpdateDeviceGammaRamp(HDEV hPDev)
Definition: icm.c:227
int32_t INT
Definition: typedefs.h:56
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
struct _PDEVOBJ * PPDEVOBJ
HCOLORSPACE hStockColorSpace
Definition: icm.c:14
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ICM_QUERY
Definition: wingdi.h:982
DRIVER_FUNCTIONS DriverFunctions
Definition: pdevobj.h:138
FLONG flFlags
Definition: pdevobj.h:89
unsigned int BOOL
Definition: ntddk_ex.h:94
HPALETTE hpalDefault
Definition: winddi.h:398
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
smooth NULL
Definition: ftsmooth.c:416
BASEOBJECT BaseObject
Definition: color.h:11
ULONG iDitherFormat
Definition: winddi.h:395
#define BMF_16BPP
Definition: winddi.h:358
#define PALETTE_ShareLockPalette(hpal)
Definition: palette.h:57
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
#define GCAPS2_CHANGEGAMMARAMP
Definition: winddi.h:370
Definition: polytest.cpp:40
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PFN_DrvIcmSetDeviceGammaRamp IcmSetDeviceGammaRamp
Definition: ntgdityp.h:635
DEVINFO devinfo
Definition: pdevobj.h:123
#define RC_PALETTE
Definition: wingdi.h:789
#define COLORSPACEOBJ_AllocCSWithHandle()
Definition: color.h:18
#define IGRF_RGB_256WORDS
Definition: winddi.h:3693
unsigned short WORD
Definition: ntddk_ex.h:93
HANDLE APIENTRY NtGdiCreateColorSpace(IN PLOGCOLORSPACEEXW pLogColorSpace)
Definition: icm.c:56
#define COLORSPACEOBJ_LockCS(hCS)
Definition: color.h:19
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
HDC hdc
Definition: main.c:9
ULONG flRaster
Definition: winddi.h:887
#define GDITAG_ICM
Definition: tags.h:125
#define ICM_OFF
Definition: wingdi.h:981
#define ICM_ON
Definition: wingdi.h:980
HDEV hPDev
Definition: palette.h:49
ULONG NumColors
Definition: palette.h:41
FLONG flFlags
Definition: palette.h:40
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
BOOL APIENTRY NtGdiSetDeviceGammaRamp(HDC hDC, LPVOID Ramp)
Definition: icm.c:367
_In_ LPLOGCOLORSPACEW pLogColorSpace
Definition: winddi.h:3673
BOOL APIENTRY NtGdiSetColorSpace(IN HDC hdc, IN HCOLORSPACE hColorSpace)
Definition: icm.c:184
Status
Definition: gdiplustypes.h:24
static HDC hDC
Definition: 3dtext.c:33
#define G(x, y, z)
Definition: md5.c:52
BOOL FASTCALL IntGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp)
Definition: icm.c:92
_SEH2_END
Definition: create.c:4424
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
WORD Blue[256]
Definition: winddi.h:777
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define PALETTE_ShareUnlockPalette(ppal)
Definition: palette.h:59
#define B(row, col)
PFN_DrvSetPalette SetPalette
Definition: ntgdityp.h:590
DWORD dwFlags
Definition: color.h:13
BOOL APIENTRY NtGdiGetDeviceGammaRamp(HDC hDC, LPVOID Ramp)
Definition: icm.c:126
unsigned int ULONG
Definition: retypes.h:1
BOOL APIENTRY NtGdiDeleteColorSpace(IN HANDLE hColorSpace)
Definition: icm.c:84
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
Definition: xlate.c:10
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2938
FLONG flGraphicsCaps2
Definition: winddi.h:399
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
INT APIENTRY NtGdiSetIcmMode(HDC hDC, ULONG nCommand, ULONG EnableICM)
Definition: icm.c:418
#define APIENTRY
Definition: api.h:79
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define COLORSPACEOBJ_UnlockCS(pCS)
Definition: color.h:20