Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

751 lines
20 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1998 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * GpBitmap.hpp
  8. *
  9. * Abstract:
  10. *
  11. * Bitmap related declarations
  12. *
  13. * Revision History:
  14. *
  15. * 12/09/1998 davidx
  16. * Created it.
  17. *
  18. \**************************************************************************/
  19. #ifndef _GPBITMAP_HPP
  20. #define _GPBITMAP_HPP
  21. #define NEARCONSTANTALPHA 0x10
  22. //--------------------------------------------------------------------------
  23. // Abstract base class for bitmap image and metafile
  24. //--------------------------------------------------------------------------
  25. class GpImage : public GpObject
  26. {
  27. protected:
  28. VOID SetValid(BOOL valid)
  29. {
  30. GpObject::SetValid(valid ? ObjectTagImage : ObjectTagInvalid);
  31. }
  32. public:
  33. // Construct a GpImage object from a disk file
  34. static GpImage* LoadImage(const WCHAR* filename);
  35. // Construct a GpImage object from a data stream
  36. static GpImage* LoadImage(IStream* stream);
  37. virtual ObjectType GetObjectType() const { return ObjectTypeImage; }
  38. // Make a copy of the image object
  39. virtual GpImage* Clone() const= 0;
  40. virtual GpImage* CloneColorAdjusted(
  41. GpRecolor * recolor,
  42. ColorAdjustType type = ColorAdjustTypeDefault
  43. ) const = 0;
  44. // Get the encoder parameter list size
  45. virtual GpStatus
  46. GetEncoderParameterListSize(
  47. CLSID* clsidEncoder,
  48. UINT* size
  49. ) = 0;
  50. // Get the encoder parameter list
  51. virtual GpStatus
  52. GetEncoderParameterList(
  53. CLSID* clsidEncoder,
  54. UINT size,
  55. OUT EncoderParameters* pBuffer
  56. ) = 0;
  57. // Save images
  58. virtual GpStatus
  59. SaveToStream(
  60. IStream* stream,
  61. CLSID* clsidEncoder,
  62. EncoderParameters* encoderParams
  63. ) = 0;
  64. virtual GpStatus
  65. SaveToFile(
  66. const WCHAR* filename,
  67. CLSID* clsidEncoder,
  68. EncoderParameters* encoderParams
  69. ) = 0;
  70. virtual GpStatus
  71. SaveAdd(
  72. const EncoderParameters* encoderParams
  73. ) = 0;
  74. virtual GpStatus
  75. SaveAdd(
  76. GpImage* newBits,
  77. const EncoderParameters* encoderParams
  78. ) = 0;
  79. // Dispose of the image object
  80. virtual VOID Dispose() = 0;
  81. // Derive a graphics context to draw into the GpImage object
  82. virtual GpGraphics* GetGraphicsContext() = 0;
  83. // Check if the GpImage object is valid
  84. virtual BOOL IsValid() const
  85. {
  86. return GpObject::IsValid(ObjectTagImage);
  87. }
  88. virtual BOOL IsSolid()
  89. {
  90. return FALSE;
  91. }
  92. virtual BOOL IsOpaque()
  93. {
  94. return FALSE;
  95. }
  96. // Get image information:
  97. // resolution
  98. // physical dimension in 0.01mm units
  99. // bounding rectangle
  100. // structure ImageInfo
  101. // thumbnail
  102. virtual GpStatus GetResolution(REAL* xdpi, REAL* ydpi) const = 0;
  103. virtual GpStatus GetPhysicalDimension(REAL* width, REAL* height) const = 0;
  104. virtual GpStatus GetBounds(GpRectF* rect, GpPageUnit* unit) const = 0;
  105. virtual GpStatus GetImageInfo(ImageInfo *imageInfo) const = 0;
  106. virtual GpStatus GetFrameCount(const GUID* dimensionID,
  107. UINT* count) const = 0;
  108. virtual GpStatus GetFrameDimensionsCount(OUT UINT* count) const = 0;
  109. virtual GpStatus GetFrameDimensionsList(OUT GUID* dimensionIDs,
  110. IN UINT count) const = 0;
  111. virtual GpStatus SelectActiveFrame(const GUID* dimensionID,
  112. UINT frameIndex) = 0;
  113. virtual GpImage* GetThumbnail(UINT thumbWidth, UINT thumbHeight,
  114. GetThumbnailImageAbort callback, VOID *callbackData) = 0;
  115. virtual GpStatus GetPalette(ColorPalette *palette, INT size) = 0;
  116. virtual GpStatus SetPalette(ColorPalette *palette) = 0;
  117. virtual INT GetPaletteSize() = 0;
  118. // Rotate and Flip
  119. virtual GpStatus RotateFlip(RotateFlipType rfType) = 0;
  120. // Property related functions
  121. virtual GpStatus GetPropertyCount(UINT* numOfProperty) = 0;
  122. virtual GpStatus GetPropertyIdList(UINT numOfProperty, PROPID* list) = 0;
  123. virtual GpStatus GetPropertyItemSize(PROPID propId, UINT* size) = 0;
  124. virtual GpStatus GetPropertyItem(PROPID propId,UINT propSize,
  125. PropertyItem* buffer) = 0;
  126. virtual GpStatus GetPropertySize(UINT* totalBufferSize,
  127. UINT* numProperties) = 0;
  128. virtual GpStatus GetAllPropertyItems(UINT totalBufferSize,
  129. UINT numProperties,
  130. PropertyItem* allItems) = 0;
  131. virtual GpStatus RemovePropertyItem(PROPID propId) = 0;
  132. virtual GpStatus SetPropertyItem(PropertyItem* item) = 0;
  133. // Determine the type of image object
  134. GpImageType GetImageType() const
  135. {
  136. return ImgType;
  137. }
  138. GpLockable* GetObjectLock() const
  139. {
  140. return &Lockable;
  141. }
  142. // Default ICM mode is off. Default behaviour for this function is to
  143. // do nothing.
  144. // If a derived class supports embedded color correction, it needs
  145. // to respect this call to turn ICM on or off.
  146. virtual VOID SetICMConvert(BOOL icm) { }
  147. private:
  148. // Prevent apps from directly using new and delete operators
  149. // on GpImage objects.
  150. GpImage()
  151. {
  152. ImgType = ImageTypeUnknown;
  153. // Set the tag in the object, even if IsValid overridden by
  154. // GpBitmap or GpMetafile.
  155. GpObject::SetValid(ObjectTagImage);
  156. }
  157. protected:
  158. GpImage(GpImageType imgType)
  159. {
  160. ImgType = imgType;
  161. // Set the tag in the object, even if IsValid overridden by
  162. // GpBitmap or GpMetafile.
  163. GpObject::SetValid(ObjectTagImage);
  164. }
  165. virtual ~GpImage() {}
  166. GpImageType ImgType; // type of image object
  167. // Object lock
  168. mutable GpLockable Lockable;
  169. };
  170. //--------------------------------------------------------------------------
  171. // Represent raster bitmap objects
  172. //--------------------------------------------------------------------------
  173. class GpDecodedImage;
  174. class GpMemoryBitmap;
  175. class CopyOnWriteBitmap;
  176. class GpBitmap : public GpImage
  177. {
  178. friend class GpObject; // for empty constructor
  179. friend class CopyOnWriteBitmap;
  180. private:
  181. CopyOnWriteBitmap * InternalBitmap;
  182. LONG ScanBitmapRef; // ref count used for when a GpGraphics is wrapped around a GpBitmap
  183. EpScanBitmap ScanBitmap;
  184. VOID IncScanBitmapRef()
  185. {
  186. InterlockedIncrement(&ScanBitmapRef);
  187. }
  188. VOID DecScanBitmapRef()
  189. {
  190. InterlockedDecrement(&ScanBitmapRef);
  191. }
  192. GpBitmap(BOOL createInternalBitmap = TRUE);
  193. GpBitmap(const GpBitmap * bitmap);
  194. GpBitmap(const CopyOnWriteBitmap * internalBitmap);
  195. // Destructor
  196. // We don't want apps to use delete operator directly.
  197. // Instead, they should use the Dispose method.
  198. virtual ~GpBitmap();
  199. protected:
  200. CopyOnWriteBitmap * LockForWrite();
  201. VOID Unlock() const;
  202. VOID LockForRead() const;
  203. public:
  204. // Constructors
  205. GpBitmap(const WCHAR* filename);
  206. GpBitmap(IStream* stream);
  207. GpBitmap(INT width, INT height, PixelFormatID format);
  208. GpBitmap(INT width, INT height, PixelFormatID format, GpGraphics * graphics);
  209. GpBitmap(
  210. INT width,
  211. INT height,
  212. INT stride, // negative for bottom-up bitmaps
  213. PixelFormatID format,
  214. BYTE * scan0
  215. );
  216. GpBitmap(
  217. BITMAPINFO* gdiBitmapInfo,
  218. VOID* gdiBitmapData,
  219. BOOL ownBitmapData
  220. );
  221. GpBitmap(IDirectDrawSurface7 *surface);
  222. // Check if the GpBitmap object is valid
  223. virtual BOOL IsValid() const;
  224. GpImage*
  225. Clone() const;
  226. GpBitmap*
  227. Clone(
  228. const GpRect* rect,
  229. PixelFormatID format = PixelFormat32bppPARGB
  230. ) const;
  231. virtual GpImage*
  232. CloneColorAdjusted(
  233. GpRecolor * recolor,
  234. ColorAdjustType type = ColorAdjustTypeDefault
  235. ) const;
  236. // Similar to CloneColorAdjusted
  237. GpStatus Recolor(
  238. GpRecolor *recolor,
  239. GpBitmap **dstBitmap,
  240. DrawImageAbort callback,
  241. VOID *callbackData,
  242. GpRect *rect = NULL
  243. );
  244. GpStatus
  245. GetEncoderParameterListSize(
  246. IN CLSID* clsidEncoder,
  247. OUT UINT* size
  248. );
  249. GpStatus
  250. GetEncoderParameterList(
  251. IN CLSID* clsidEncoder,
  252. IN UINT size,
  253. OUT EncoderParameters* pBuffer
  254. );
  255. GpStatus
  256. SaveToStream(
  257. IStream* stream,
  258. CLSID* clsidEncoder,
  259. EncoderParameters* encoderParams
  260. );
  261. GpStatus
  262. SaveToFile(
  263. const WCHAR* filename,
  264. CLSID* clsidEncoder,
  265. EncoderParameters* encoderParams
  266. );
  267. GpStatus
  268. SaveAdd(
  269. const EncoderParameters* encoderParams
  270. );
  271. GpStatus
  272. SaveAdd(
  273. GpImage* newBits,
  274. const EncoderParameters* encoderParams
  275. );
  276. // Dispose the bitmap object
  277. VOID Dispose();
  278. // Get bitmap information
  279. virtual GpStatus GetResolution(REAL* xdpi, REAL* ydpi) const;
  280. virtual GpStatus GetPhysicalDimension(REAL* width, REAL* height) const;
  281. virtual GpStatus GetBounds(GpRectF* rect, GpPageUnit* unit) const;
  282. virtual GpStatus GetSize(Size* size) const;
  283. virtual GpStatus GetImageInfo(ImageInfo *imageInfo) const;
  284. virtual GpImage* GetThumbnail(UINT thumbWidth, UINT thumbHeight,
  285. GetThumbnailImageAbort callback,
  286. VOID *callbackData);
  287. virtual GpStatus GetFrameCount(const GUID* dimensionID,
  288. UINT* count) const;
  289. virtual GpStatus GetFrameDimensionsCount(OUT UINT* count) const;
  290. virtual GpStatus GetFrameDimensionsList(OUT GUID* dimensionIDs,
  291. IN UINT count) const;
  292. virtual GpStatus SelectActiveFrame(const GUID* dimensionID,
  293. UINT frameIndex);
  294. virtual GpStatus GetPalette(ColorPalette *palette, INT size);
  295. virtual GpStatus SetPalette(ColorPalette *palette);
  296. virtual INT GetPaletteSize();
  297. GpStatus GetTransparencyHint(DpTransparency* transparency);
  298. GpStatus SetTransparencyHint(DpTransparency transparency);
  299. GpStatus GetTransparencyFlags(DpTransparency* transparency,
  300. PixelFormatID loadFormat = PixelFormatDontCare,
  301. BYTE* minAlpha = NULL,
  302. BYTE* maxAlpha = NULL);
  303. // Property related functions
  304. virtual GpStatus GetPropertyCount(UINT* numOfProperty);
  305. virtual GpStatus GetPropertyIdList(UINT numOfProperty, PROPID* list);
  306. virtual GpStatus GetPropertyItemSize(PROPID propId, UINT* size);
  307. virtual GpStatus GetPropertyItem(PROPID propId,UINT propSize,
  308. PropertyItem* buffer);
  309. virtual GpStatus GetPropertySize(UINT* totalBufferSize,UINT* numProperties);
  310. virtual GpStatus GetAllPropertyItems(UINT totalBufferSize,
  311. UINT numProperties,
  312. PropertyItem* allItems);
  313. virtual GpStatus RemovePropertyItem(PROPID propId);
  314. virtual GpStatus SetPropertyItem(PropertyItem* item);
  315. // Retrieve bitmap data
  316. GpStatus
  317. LockBits(
  318. const GpRect* rect,
  319. UINT flags,
  320. PixelFormatID pixelFormat,
  321. BitmapData* bmpdata,
  322. INT width = 0,
  323. INT height = 0
  324. ) const;
  325. GpStatus
  326. UnlockBits(
  327. BitmapData* bmpdata,
  328. BOOL Destroy=FALSE
  329. ) const;
  330. // Flush batched drawing operations and optionally wait for drawing to
  331. // complete. This is currently a nop operation. If the behavior
  332. // of a GpBitmap changes to a model where rendering operations are
  333. // non-immediate then this routine will need to be implemented.
  334. VOID
  335. Flush(GpFlushIntention intention) {};
  336. // Get and set pixel on the bitmap.
  337. GpStatus GetPixel(INT x, INT y, ARGB *color);
  338. GpStatus SetPixel(INT x, INT y, ARGB color);
  339. // Rotate and Flip
  340. GpStatus RotateFlip(
  341. RotateFlipType rfType
  342. );
  343. // Derive a graphics context on top of the bitmap object
  344. GpGraphics* GetGraphicsContext();
  345. GpStatus
  346. GpBitmap::InitializeSurfaceForGdipBitmap(
  347. DpBitmap * surface,
  348. INT width,
  349. INT height
  350. );
  351. // Derive an HDC for interop on top of the bitmap object
  352. HDC GetHdc();
  353. VOID ReleaseHdc(HDC hdc);
  354. // Serialization
  355. virtual UINT GetDataSize() const;
  356. virtual GpStatus GetData(IStream * stream) const;
  357. virtual GpStatus SetData(const BYTE * dataBuffer, UINT size);
  358. GpStatus GetCompressedData(
  359. DpCompressedData * compressed_data,
  360. BOOL getJPEG = TRUE,
  361. BOOL getPNG = TRUE,
  362. HDC hdc = (HDC)NULL);
  363. GpStatus DeleteCompressedData(
  364. DpCompressedData * compressed_data);
  365. BOOL IsDirty() const;
  366. // Color adjust
  367. virtual GpStatus ColorAdjust(
  368. GpRecolor * recolor,
  369. ColorAdjustType type
  370. );
  371. GpStatus
  372. ColorAdjust(
  373. GpRecolor * recolor,
  374. PixelFormatID pixfmt,
  375. DrawImageAbort callback,
  376. VOID *callbackData
  377. );
  378. GpStatus GetPixelFormatID(PixelFormatID* pixfmt);
  379. enum
  380. {
  381. Invalid = 0, // bitmap object is invalid
  382. ImageRef = 1, // contains a reference only (e.g. filename)
  383. ExtStream = 2, // contains a reference to a stream
  384. DecodedImg = 3, // contains a decoded image object,
  385. // but it's not decoded yet - name is misleading.
  386. MemBitmap = 4 // contains an in-memory bitmap object
  387. };
  388. INT GetDecodeState();
  389. GpStatus ForceValidation();
  390. GpStatus SetResolution(REAL xdpi, REAL ydpi);
  391. GpStatus
  392. PreDraw(
  393. INT numPoints,
  394. GpPointF *dstPoints,
  395. GpRectF *srcRect,
  396. INT numBitsPerPixel
  397. );
  398. DWORD GetUniqueness() { return (DWORD)GetUid(); }
  399. // Interop:
  400. static GpStatus CreateFromHBITMAP(
  401. HBITMAP hbm,
  402. HPALETTE hpal,
  403. GpBitmap** bitmap
  404. );
  405. static GpStatus CreateBitmapAndFillWithBrush(
  406. InterpolationMode interpolationMode,
  407. PixelOffsetMode pixelOffsetMode,
  408. const GpMatrix * worldToDevice,
  409. const GpRect * drawBounds,
  410. GpBrush * brush,
  411. GpBitmap ** bitmap,
  412. PixelFormatID pixelFormat = PIXFMT_32BPP_ARGB
  413. );
  414. static GpStatus DrawAndHalftoneForStretchBlt(
  415. HDC hdc,
  416. BITMAPINFO * bmpInfo,
  417. BYTE * bits,
  418. INT srcX,
  419. INT srcY,
  420. INT srcWidth,
  421. INT srcHeight,
  422. INT destWidth,
  423. INT destHeight,
  424. BITMAPINFO ** destBmpInfo,
  425. BYTE ** destBmpBits,
  426. HBITMAP * destDIBSection,
  427. InterpolationMode interpolationMode
  428. );
  429. GpStatus CreateHBITMAP(HBITMAP *phbm, ARGB background);
  430. GpStatus ICMFrontEnd(
  431. GpBitmap **dstBitmap,
  432. DrawImageAbort callback,
  433. VOID *callbackData,
  434. GpRect *rect = NULL
  435. );
  436. static GpStatus CreateFromHICON(
  437. HICON hicon,
  438. GpBitmap** bitmap
  439. );
  440. GpStatus CreateHICON(HICON *phicon);
  441. static GpStatus CreateFromResource(
  442. HINSTANCE hInstance,
  443. LPWSTR lpBitmapName,
  444. GpBitmap** bitmap
  445. );
  446. // We need to know if the bitmap is associated with a display
  447. // so we know how to handle the page transform when it is
  448. // set to UnitDisplay.
  449. BOOL IsDisplay() const;
  450. VOID SetDisplay(BOOL display);
  451. BOOL IsICMConvert() const;
  452. virtual VOID SetICMConvert(BOOL icm);
  453. };
  454. // This is the base class for any class that implements the CopyOnWrite
  455. // technology that enable cloning to be very light-weight when cloning for
  456. // read access. It implements read and write locking for synchronization
  457. // using a critical section, and it keeps track of reference counting
  458. // the object so that it can be deleted at the right time.
  459. class CopyOnWrite
  460. {
  461. protected:
  462. // Constructor: notice that when an object is first
  463. // created, its reference count is set to 1.
  464. CopyOnWrite()
  465. {
  466. RefCount = 1;
  467. #if DBG
  468. Lock = NotLocked;
  469. LockCount = 0;
  470. #endif
  471. InitializeCriticalSection(&Semaphore);
  472. }
  473. virtual ~CopyOnWrite()
  474. {
  475. DeleteCriticalSection(&Semaphore);
  476. }
  477. #if DBG
  478. enum LockedType
  479. {
  480. NotLocked,
  481. LockedForRead,
  482. LockedForWrite
  483. };
  484. #endif
  485. virtual CopyOnWrite * Clone() const = 0;
  486. virtual BOOL IsValid() const = 0;
  487. // Returns NULL if it fails to lock for writing
  488. CopyOnWrite * LockForWrite()
  489. {
  490. EnterCriticalSection(&Semaphore);
  491. CopyOnWrite * writeableObject = this;
  492. // If there is more than one reference to this object, we must
  493. // clone it before giving write access to it.
  494. if (RefCount > 1)
  495. {
  496. writeableObject = this->Clone();
  497. if (writeableObject == NULL)
  498. {
  499. LeaveCriticalSection(&Semaphore);
  500. return NULL;
  501. }
  502. ASSERT(writeableObject->IsValid());
  503. // else we succeeded in cloning the object
  504. RefCount--;
  505. EnterCriticalSection(&(writeableObject->Semaphore));
  506. LeaveCriticalSection(&Semaphore);
  507. }
  508. #if DBG
  509. writeableObject->Lock = LockedForWrite;
  510. writeableObject->LockCount++;
  511. #endif
  512. return writeableObject;
  513. }
  514. VOID LockForRead() const
  515. {
  516. EnterCriticalSection(&Semaphore);
  517. #if DBG
  518. if (Lock == NotLocked)
  519. {
  520. Lock = LockedForRead;
  521. }
  522. LockCount++;
  523. #endif
  524. }
  525. VOID Unlock() const
  526. {
  527. #if DBG
  528. ASSERT(Lock != NotLocked);
  529. if (--LockCount <= 0)
  530. {
  531. Lock = NotLocked;
  532. LockCount = 0;
  533. }
  534. #endif
  535. LeaveCriticalSection(&Semaphore);
  536. }
  537. // Increment reference count
  538. // Note that we must use the critical section to control access, rather
  539. // than using interlocked increment.
  540. LONG AddRef() const
  541. {
  542. EnterCriticalSection(&Semaphore);
  543. RefCount++;
  544. LeaveCriticalSection(&Semaphore);
  545. return RefCount;
  546. }
  547. // Decrement reference count
  548. // Note that we must use the critical section to control access, rather
  549. // than using interlocked decrement.
  550. LONG Release() const
  551. {
  552. EnterCriticalSection(&Semaphore);
  553. ULONG count = --RefCount;
  554. // must leave the critical section before calling delete so that
  555. // we don't try to access the freed memory.
  556. LeaveCriticalSection(&Semaphore);
  557. if (count == 0)
  558. {
  559. delete this;
  560. }
  561. return count;
  562. }
  563. private:
  564. mutable LONG RefCount;
  565. mutable CRITICAL_SECTION Semaphore;
  566. #if DBG
  567. mutable INT LockCount;
  568. protected:
  569. mutable LockedType Lock;
  570. #endif
  571. };
  572. GpStatus
  573. ConvertTo16BppAndFlip(
  574. GpBitmap * sourceBitmap,
  575. GpBitmap * & destBitmap
  576. );
  577. VOID
  578. HalftoneColorRef_216(
  579. COLORREF color, // color to halftone
  580. UNALIGNED VOID *dib // packed 8 bpp DIB buffer with 8 colors
  581. // The DIB buffer should be this size:
  582. // sizeof(BITMAPINFOHEADER) + // DIB 8 bpp header
  583. // (8 * sizeof(RGBQUAD)) + // DIB 8 colors
  584. // (8 * 8) // DIB 8x8 pixels
  585. );
  586. #endif // !_GPBITMAP_HPP