Source code of Windows XP (NT5)
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.

533 lines
14 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: 32BITDIB.H
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: t-JacobR
  10. *
  11. * DATE: 1/11/2000
  12. *
  13. * DESCRIPTION:
  14. *
  15. * C32BitDibWrapper provides support for a number of common graphics special
  16. * effects for this class, 32 bit dibs are stored in the following format: 8
  17. * ignored high order bits followed by 8 bits per RGB chan. warning: many
  18. * functions in this class will reset the 8 high order bits so it is not
  19. * practical to add additional functions which use an 8 bit alpha chan
  20. *
  21. * Notes:
  22. *
  23. * The blur function is designed so that it can be combined with the
  24. * difference function to create an edge detection filter More specifically,
  25. * the blur function takes the average of only the four pixels around the
  26. * current pixel instead of including the current pixel in the average.
  27. *
  28. *******************************************************************************/
  29. #ifndef __32BITDIB_H_INCLUDED
  30. #define __32BITDIB_H_INCLUDED
  31. //
  32. // Constants used for Region Detection
  33. //
  34. #define MERGE_REGIONS TRUE
  35. #define MAXREGIONS 10000
  36. #define PHOTOGRAPH_REGION 1
  37. #define TEXT_REGION 2
  38. //
  39. // We don't want lowlife text regions which are probably stray dots merging with
  40. // photograph regions this id certifies that a text region is big enough to merge
  41. // with a photograph
  42. //
  43. #define MERGABLE_WITH_PHOTOGRAPH 16
  44. //
  45. // how many pixels before you are too big to even imagine that you are a stray blot
  46. //
  47. #define LARGEREGION_THRESHOLD 10000
  48. //
  49. // pixels
  50. //
  51. #define MINREGIONSIZE 10
  52. //
  53. // how far down should we sample the the image?
  54. // goal to sample down the image to
  55. //
  56. #define GOALX 300
  57. #define GOALY 400
  58. //
  59. // borderline in function between text regions and photo regions
  60. //
  61. #define MIN_BORDERLINE_TEXTPHOTO 10
  62. //
  63. // If in borderline, we apply extra functions to determine if its really
  64. // a text region or not
  65. //
  66. #define TEXTPHOTO_THRESHOLD 15
  67. #define MAX_BORDERLINE_TEXTPHOTO 1500
  68. //
  69. // Note... we won't consider merging two photo regions if both regions
  70. // are greater than MAX_MERGABLE_PHOTOGRAPH_SIZE
  71. //
  72. #define MAX_MERGE_PHOTO_REGIONS 2
  73. #define MAX_NO_EDGE_PIXEL_REGION_PENALTY 16
  74. //
  75. // Maximum merge radius for regions where one region is text and one is a photo region
  76. //
  77. #define MAX_MERGE_DIFFERENT_REGIONS 13
  78. //
  79. // If you are close to the edge after this long you very well might be a stray blot
  80. //
  81. #define BORDER_EXTREME_EDGE_PIXEL_REGION_PENALTY 45
  82. //
  83. // maximum merging radius for text regions merged with text regions
  84. // note: no merging takes place between photo regions and photo regions
  85. //
  86. #define MAXBORDER 65
  87. //
  88. // maximum border width where we can look the other way when it comes to
  89. // collision detection collsion detection is somewhat expensive so only use
  90. // it when we are dealing with signifigant spacings. we only want to use
  91. // collision detection to make sure that we don't create regions through
  92. // previously deleted shadows, etc. constants for deciding if a region is a
  93. // valid region
  94. //
  95. // NOTE: we never do collision detection for merging photo regions... for
  96. // obvious reasons... we only want to merge photo regions which are part of
  97. // the same region... hence we would actually only want to merge photograph
  98. // regions where there was a pretty high collision factor
  99. //
  100. #define MERGABLE_WITHOUT_COLLISIONDETECTION 668
  101. //
  102. // minimum region width
  103. //
  104. #define MINWIDTH 5
  105. #define MINPHOTOWIDTH 5
  106. //
  107. // maximum ratio between height and width
  108. //
  109. #define MAXREGIONRATIO 81
  110. #define MAXPHOTORATIO 81
  111. #define MINSIZE 30
  112. //
  113. // if you are more than 6 pixels wide, you are ok. we don't care what your aspect ratio is
  114. //
  115. #define IGNORE_RATIO_WIDTH 6
  116. //
  117. // number of pixels required before we throw a region out as being just a
  118. // stray dot (10 x 10 so it isn't a huge requirement)
  119. //
  120. #define MINREGIONPIXELS 20
  121. //
  122. // very conservative
  123. //
  124. #define MINPPHOTOSELECTEDFACTOR 5
  125. //
  126. // conservative.. its unlikely that many regions will have edge factors this low
  127. //
  128. #define MINEDGEFACTOR 5
  129. //
  130. // allow a couple of black pixels without going crazy
  131. //
  132. #define MAX_RESISTANCE_ALLOWED_TO_UNION 1024
  133. #define DONE_WITH_BORDER_CHECKING -1
  134. #define MIN_FINAL_REGION_SIZE 38
  135. #define CLOSE_TO_EDGE_PENALTY_WIDTH 3
  136. //
  137. // the following are designed to weed out speckles. these are only applied
  138. // after we have increased the border past MAX_MERGE_DIFFERENT_REGIONS. so
  139. // all that should be left is small text regions and long and narrow
  140. // speckles.
  141. //
  142. //
  143. // no close to edge penalty factor
  144. //
  145. #define CLOSE_TO_EDGE_PENALTY_FACTOR 1
  146. #define UNKNOWN -1
  147. #define EDGE_PENALTY_WIDTH 2
  148. //
  149. // 2x all requirements if region is within EDGE_PENALTY_WIDTH from the edge
  150. // of the image. some requirements may be multiplied by EDGE_PENALTY_FACTOR
  151. // squared... i.e. for 2D requirments like num of pixels
  152. //
  153. #define EDGE_PENALTY_FACTOR 1
  154. #define COMPARISON_ERROR_RADIUS 2
  155. //
  156. // constants used for findchunk filters so that we aren't lead astray by the
  157. // possible black ring around the image
  158. //
  159. #define VERTICAL_EDGE -1
  160. #define HORIZONTAL_EDGE -2
  161. //
  162. // a nice massive stack which is large enough that we are gauranteed never to exceed it
  163. //
  164. #define MAXSTACK (GOALX*GOALY)
  165. //
  166. // we do two remove shadow passes.
  167. // one pass is intended to only remove shadows
  168. // the other is designed to handle scanners which have yellow lids, etc.
  169. //
  170. //
  171. // maximum intensity allowed for first pixel of a shadow.. we used to
  172. // think that we should only let shadows start at 0... that was before we
  173. // saw the light
  174. //
  175. #define MAXSHADOWSTART 800
  176. //
  177. // maximum edge value permitted for a shadow pixel
  178. //
  179. #define MAXSHADOWPIXEL 3
  180. //
  181. // if we are near the edge, we want to kill anything that is remotely like a shadow
  182. //
  183. #define MAXEDGESHADOWPIXEL 20
  184. #define MAX_DIFFERENCE_FROM_GRAY 690
  185. //
  186. // border where we do tougher despeckle & edge filters...
  187. //
  188. #define DESPECKLE_BORDER_WIDTH 6
  189. //
  190. // the background color remove shadows algorithm pass is at the moment the
  191. // same as the first pass. we may later want to optumize it to better do its
  192. // specific task.. for example... for this filter, we could care less about
  193. // if a pixel isn't grey
  194. //
  195. //
  196. // accept all pixels
  197. //
  198. #define FIX_BACKGROUND_MAXSHADOWSTART 800
  199. #define FIX_BACKGROUND_MAXSHADOWPIXEL 2
  200. //
  201. // maximum intensity to be considered a bonified text region background pixel
  202. //
  203. #define TEXT_REGION_BACKGROUND_THRESHOLD 31
  204. //
  205. // this if for use with Pixels below Threshold which should be called using
  206. // the origional image... not an inverted image
  207. //
  208. //
  209. // minimum edge value to earn the distinguished title of being a text region edge pixel
  210. //
  211. #define MIN_TEXT_REGION_BACKGROUND_EDGE 32
  212. //
  213. // minimum edge value to earn the distinguished title of being a text region edge pixel
  214. //
  215. #define MIN_TEXT_REGION_BACKGROUND_EDGE_CLIPPED_PIXEL 120
  216. #define CLIPPED_TEXT_REGION_BACKGROUND_THRESHOLD 180
  217. //
  218. // not implemented yet
  219. //
  220. #define TEXT_REGION_BACKGROUND_PIXEL_MAX_CLIPPED_DIFFERENCE_FROM_GREY 32
  221. //
  222. // minimum intensity to select a pixel
  223. //
  224. #define MIN_CHUNK_INTENSITY 48
  225. //
  226. // should be 0, but different values are useful for debugging... although
  227. // extreme values will potentially mess up region detection its the color we
  228. // set erased shadow bits
  229. //
  230. #define ERASEDSHADOW 0
  231. // beta constants:
  232. //
  233. // idea: inverted images... and constant color image potential problems
  234. //
  235. #define COLLISION_DETECTION_HIGHPASS_VALUE 600
  236. //
  237. // if a photograph gets fragmented we will see a bunch of closely spaced and
  238. // relatively small regions only one of the two regions has to be bellow this
  239. // size requirement to merge them as part way through the merge proccess we
  240. // will be definition have a larger region than this const or the const isn't
  241. // fullfilling its purpose
  242. //
  243. #define MAX_MERGABLE_PHOTOGRAPH_SIZE 30000
  244. #define NOT_SHADOW 0x800ff09
  245. //
  246. // a pixel which we are sure is bad and that we will no
  247. // rejuvinate no matter that edge val it may have
  248. //
  249. #define DEAD_PIXEL 0x8000002
  250. //
  251. // minimum edge intensity to classify a pixel as NOT_SHADOW
  252. //
  253. #define NOT_SHADOW_INTENSITY 28
  254. #define MIN_WALL_INTENSITY 200
  255. #define MIN_BLACK_SCANNER_EDGE_CHAN_VALUE 110
  256. #define MAX_BLACK_BORDER_DELTA 12
  257. #define MAX_KILL_SHADOW_BACKGROUND_APROXIMATION 64
  258. #define MAX_KILL_SHADOW_BACKGROUND_UNEDITED 200
  259. //
  260. // further ideas: to eliminate the possibility of embarassing errors: count
  261. // the number of background pixels if the num of background pixels is above a
  262. // threshold use weaker shadow and edge filters as we probably have a good
  263. // scanner something like if half the page is defined as background pixels
  264. // dangers: white page on a horrible scanner
  265. //
  266. //
  267. // MORE IMPORTANTLY: also the select region search radius TIP: if you are
  268. // running multiple region selection, an EDGEWIDTH of 3 or more could limit
  269. // your options considerably as nearby regions may get merged together
  270. // particularly when using edge enhancement and when GOALX is set at 300 or
  271. // less
  272. //
  273. #define EDGEWIDTH 2
  274. //
  275. // color used to highlight clipped pixels while debugging the code for eliminating black borders
  276. //
  277. #define DEBUGCOLOR 0xff0000
  278. #define FIGHTING_EDGES FALSE
  279. //
  280. // you better be darn close to grey to get marked as NOT_SHADOW fighting
  281. // edges involve pixeled being marked as not possibly being edges as well as
  282. // pixels
  283. //
  284. #define FIGHTING_EDGES_DIFF_FROM_GREY 10
  285. //
  286. // being marked as definite edges
  287. //
  288. #define FIGHTING_EDGE_MIN_MARK_PIXEL 10
  289. #define FIGHTING_EDGE_MAX_MARK_PIXEL 210
  290. #define FIGHTING_EDGE_MAX_EDGE 1
  291. #define BORDER_EDGE 0xfffffff
  292. //
  293. // used for killing the black border around the page
  294. //
  295. #define CORNER_WIDTH 5
  296. //
  297. // used for black border removal
  298. //
  299. #define SHADOW_HEIGHT 10
  300. #define VISUAL_DEBUG FALSE
  301. #define SMOOTH_BORDER FALSE
  302. //
  303. // amount to increase border while unioning together regions for single region
  304. // region detection
  305. //
  306. #define SINGLE_REGION_BORDER_INCREMENT 4
  307. class C32BitDibWrapper
  308. {
  309. private:
  310. //
  311. // No implementation
  312. //
  313. C32BitDibWrapper &operator=( const C32BitDibWrapper & );
  314. C32BitDibWrapper( const C32BitDibWrapper & );
  315. public:
  316. explicit C32BitDibWrapper(BITMAP pBitmap);
  317. //
  318. // Copy constructor... create a new dib wrapper with a copy of all the data in the other dib wrapper
  319. //
  320. explicit C32BitDibWrapper(C32BitDibWrapper *pBitmap);
  321. //
  322. // construct wrapper from a dib
  323. //
  324. explicit C32BitDibWrapper(BYTE* pDib);
  325. //
  326. // creates an uninitialized dib wrapper
  327. //
  328. C32BitDibWrapper(void);
  329. //
  330. // creates a blank dib
  331. //
  332. C32BitDibWrapper(int w, int h);
  333. virtual ~C32BitDibWrapper(void);
  334. void Destroy(void);
  335. //
  336. // functions for common graphics effects
  337. //
  338. int Blur(void);
  339. BYTE* pointerToBlur(void);
  340. BYTE* pointerToHorizontalBlur(void);
  341. BYTE* pointerToVerticalBlur(void);
  342. int CreateBlurBitmap(C32BitDibWrapper * pSource);
  343. int CreateHorizontalBlurBitmap(C32BitDibWrapper * pSource);
  344. int CreateVerticalBlurBitmap(C32BitDibWrapper * pSource);
  345. //
  346. // Creates a new dib where each pixel is equal to the difference
  347. // of the pixel values for the other two dibs
  348. //
  349. int CreateDifferenceBitmap (C32BitDibWrapper *pBitmap1, C32BitDibWrapper *pBitmap2);
  350. int KillShadows(C32BitDibWrapper * pEdgeBitmap, ULONG start, ULONG maxPixel, ULONG differenceFromGrey, ULONG min_guaranteed_not_shadow, bool enhanceEdges);
  351. void RemoveBlackBorder(int minBlackBorderPixel, C32BitDibWrapper * outputBitmap,C32BitDibWrapper * debugBitmap);
  352. //
  353. // resample image down to half size
  354. //
  355. int HalfSize(void);
  356. //
  357. // resample image down to half intensity
  358. //
  359. int HalfIntensity(void);
  360. void Invert(void);
  361. //
  362. // less common graphics filters:
  363. //
  364. void Despeckle(void);
  365. //
  366. // only despeckle the outer edge of pixels in the image
  367. //
  368. void EdgeDespeckle(void);
  369. //
  370. // despeckles the ith pixel in a bitmap
  371. //
  372. void DespecklePixel(ULONG* bitmapPixels, int i, bool edgePixel);
  373. void CorrectBrightness(void);
  374. void MaxContrast(UINT numPixelsRequired);
  375. void AdjustForBadScannerBedColor(C32BitDibWrapper * edgeBitmap);
  376. //
  377. // Similar to a photoshop magic wand.. just we try to run our magic wand starting from ever possible pixel
  378. //
  379. int FindChunks(int * pMap);
  380. //
  381. // display selected chunks... for debugging purposes mostly
  382. //
  383. void ColorChunks(int * pMap);
  384. int PixelsBelowThreshold(C32BitDibWrapper* pProccessed, C32BitDibWrapper * pEdges, RECT region);
  385. BYTE* ConvertBitmap(BYTE* pSource, int bitsPerSource, int bitsPerDest);
  386. //
  387. // for debugging purposes only
  388. // MyBitBlt is horribly slow as we manually convert the
  389. // bitmap to a 24 bit dib before displaying
  390. //
  391. int Draw(HDC hdc, int x, int y);
  392. inline void SetPixel(int x, int y, ULONG color);
  393. inline ULONG GetPixel(int x, int y);
  394. //
  395. // calculates the total color intensity of a line
  396. //
  397. ULONG Line(int x1, int y1, int x2, int y2);
  398. private:
  399. //
  400. // line drawing helper functions
  401. //
  402. ULONG Octant0(int X0, int Y0,int DeltaX,int DeltaY,int XDirection);
  403. ULONG Octant1(int X0, int Y0,int DeltaX,int DeltaY,int XDirection);
  404. //
  405. // kill borders helper function:
  406. //
  407. void KillBlackBorder(int minBlackBorderPixel, int startPosition, int width, int height, int dx, int dy, C32BitDibWrapper *pOutputBitmap, C32BitDibWrapper * pDebugBitmap);
  408. public:
  409. void CompensateForBackgroundColor(int r, int g, int b);
  410. ULONG CalculateBackgroundColor(void);
  411. bool IsValid(void)
  412. {
  413. return (m_pBits && m_nBitmapWidth != -1 && m_nBitmapHeight != -1);
  414. }
  415. public:
  416. BYTE *m_pBits;
  417. int m_nBitmapWidth;
  418. int m_nBitmapHeight;
  419. };
  420. //
  421. // dib manipulation functions
  422. //
  423. void SetBMI( PBITMAPINFO pbmi, LONG width, LONG height, LONG depth );
  424. PBYTE AllocDibFileFromBits( PBYTE pBits, UINT width, UINT height, UINT depth );
  425. HBITMAP DIBBufferToBMP( HDC hDC, PBYTE pDib, BOOLEAN bFlip );
  426. HRESULT ReadDIBFile( LPTSTR pszFileName, PBYTE *ppDib );
  427. LONG GetBmiSize( PBITMAPINFO pbmi );
  428. INT GetColorTableSize( UINT uBitCount, UINT uCompression );
  429. DWORD CalcBitsSize( UINT uWidth, UINT uHeight, UINT uBitCount, UINT uPlanes, int nAlign );
  430. HGLOBAL BitmapToDIB( HDC hdc, HBITMAP hBitmap );
  431. #endif // __32BITDIB_H_INCLUDED