helper_video.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:15k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: helper_video.c 548 2006-01-08 22:41:57Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. bool_t EqSubtitle(const subtitle* a, const subtitle* b)
  25. {
  26. return a->FourCC == b->FourCC;
  27. }
  28. bool_t EqAudio(const audio* a, const audio* b)
  29. {
  30. return a->Bits == b->Bits &&
  31.    a->Channels == b->Channels &&
  32.    a->SampleRate == b->SampleRate &&
  33.    a->FracBits == b->FracBits &&
  34.    a->Flags == b->Flags &&
  35.    a->Format == b->Format;
  36. }
  37. bool_t EqFrac(const fraction* a, const fraction* b)
  38. {
  39. if (a->Den == b->Den && a->Num == b->Num) 
  40. return 1;
  41. if (!a->Den) return b->Den==0;
  42. if (!b->Den) return 0;
  43. return (int64_t)b->Den * a->Num == (int64_t)a->Den * b->Num;
  44. }
  45. int BitMaskSize(uint32_t Mask)
  46. {
  47. int i;
  48. for (i=0;Mask;++i)
  49. Mask &= Mask - 1;
  50. return i;
  51. }
  52. int BitMaskPos(uint32_t Mask)
  53. {
  54. int i;
  55. for (i=0;Mask && !(Mask&1);++i) 
  56. Mask >>= 1;
  57. return i;
  58. }
  59. int ScaleRound(int v,int Num,int Den)
  60. {
  61. int64_t i;
  62. if (!Den) 
  63. return 0;
  64. i = (int64_t)v * Num;
  65. if (i<0)
  66. i-=Den/2;
  67. else
  68. i+=Den/2;
  69. i/=Den;
  70. return (int)i;
  71. }
  72. void FillColor(uint8_t* Dst,int DstPitch,int x,int y,int Width,int Height,int BPP,int Value)
  73. {
  74. if (Width>0 && Height>0)
  75. {
  76. uint16_t *p16,*p16e;
  77. uint32_t *p32,*p32e;
  78. uint8_t* End;
  79. Dst += y*DstPitch + (x*BPP)/8;
  80. End = Dst + Height * DstPitch;
  81. do
  82. {
  83. switch (BPP)
  84. {
  85. case 1:
  86. Value &= 1;
  87. memset(Dst,Value * 0xFF,Width >> 3);
  88. break;
  89. case 2:
  90. Value &= 3;
  91. memset(Dst,Value * 0x55,Width >> 2);
  92. break;
  93. case 4:
  94. Value &= 15;
  95. memset(Dst,Value * 0x11,Width >> 1);
  96. break;
  97. case 8:
  98. memset(Dst,Value,Width);
  99. break;
  100. case 16:
  101. p16 = (uint16_t*)Dst;
  102. p16e = p16+Width;
  103. for (;p16!=p16e;++p16)
  104. *p16 = (uint16_t)Value;
  105. break;
  106. case 32:
  107. p32 = (uint32_t*)Dst;
  108. p32e = p32+Width;
  109. for (;p32!=p32e;++p32)
  110. *p32 = Value;
  111. break;
  112. }
  113. Dst += DstPitch;
  114. }
  115. while (Dst != End);
  116. }
  117. }
  118. bool_t EqBlitFX(const blitfx* a, const blitfx* b)
  119. {
  120. return a->Flags == b->Flags &&
  121.    a->Contrast == b->Contrast &&
  122.    a->Saturation == b->Saturation &&
  123.    a->Brightness == b->Brightness &&
  124.    a->Direction == b->Direction &&
  125.    a->RGBAdjust[0] == b->RGBAdjust[0] &&
  126.    a->RGBAdjust[1] == b->RGBAdjust[1] &&
  127.    a->RGBAdjust[2] == b->RGBAdjust[2] &&
  128.    a->ScaleX == b->ScaleX &&
  129.    a->ScaleY == b->ScaleY;
  130. }
  131. int CombineDir(int Src, int Blit, int Dst)
  132. {
  133. //order of transformations 
  134. //  SrcMirror
  135. //  SrcSwap
  136. //  BlitSwap
  137. //  BlitMirror
  138. //  DstSwap
  139. //  DstMirror
  140. //should be combined to a single
  141. //  Swap
  142. //  Mirror
  143. if (Dst & DIR_SWAPXY)
  144. {
  145. if (Blit & DIR_MIRRORLEFTRIGHT)
  146. Dst ^= DIR_MIRRORUPDOWN;
  147. if (Blit & DIR_MIRRORUPDOWN)
  148. Dst ^= DIR_MIRRORLEFTRIGHT;
  149. }
  150. else
  151. Dst ^= Blit & (DIR_MIRRORUPDOWN|DIR_MIRRORLEFTRIGHT);
  152. Dst ^= Blit & DIR_SWAPXY;
  153. Dst ^= Src & DIR_SWAPXY;
  154. if (Dst & DIR_SWAPXY)
  155. {
  156. if (Src & DIR_MIRRORLEFTRIGHT)
  157. Dst ^= DIR_MIRRORUPDOWN;
  158. if (Src & DIR_MIRRORUPDOWN)
  159. Dst ^= DIR_MIRRORLEFTRIGHT;
  160. }
  161. else
  162. Dst ^= Src & (DIR_MIRRORUPDOWN|DIR_MIRRORLEFTRIGHT);
  163. return Dst;
  164. }
  165. int SurfaceRotate(const video* SrcFormat, const video* DstFormat, 
  166.   const planes Src, planes Dst, int Dir)
  167. {
  168. blitfx FX;
  169. memset(&FX,0,sizeof(FX));
  170. FX.ScaleX = SCALE_ONE;
  171. FX.ScaleY = SCALE_ONE;
  172. FX.Direction = Dir;
  173. return SurfaceCopy(SrcFormat,DstFormat,Src,Dst,&FX);
  174. }
  175. int SurfaceCopy(const video* SrcFormat, const video* DstFormat, 
  176. const planes Src, planes Dst, const blitfx* FX)
  177. {
  178. void* Blit;
  179. rect SrcRect;
  180. rect DstRect;
  181. VirtToPhy(NULL,&SrcRect,SrcFormat);
  182. VirtToPhy(NULL,&DstRect,DstFormat);
  183. Blit = BlitCreate(DstFormat,SrcFormat,FX,NULL);
  184. if (!Blit)
  185. return ERR_NOT_SUPPORTED;
  186. BlitAlign(Blit,&DstRect,&SrcRect);
  187. BlitImage(Blit,Dst,*(const constplanes*)Src,NULL,-1,-1);
  188. BlitRelease(Blit);
  189. return ERR_NONE;
  190. }
  191. int SurfaceAlloc(planes Ptr, const video* p)
  192. {
  193. int i;
  194. for (i=0;i<MAXPLANES;++i)
  195. Ptr[i] = NULL;
  196. if (p->Pixel.Flags & (PF_YUV420|PF_YUV422|PF_YUV444|PF_YUV410))
  197. {
  198. int x,y,s;
  199. PlanarYUV(&p->Pixel,&x,&y,&s);
  200. Ptr[0] = Alloc16(p->Height * p->Pitch);
  201. Ptr[1] = Alloc16((p->Height>>y) * (p->Pitch>>s));
  202. Ptr[2] = Alloc16((p->Height>>y) * (p->Pitch>>s));
  203. if (!Ptr[0] || !Ptr[1] || !Ptr[2])
  204. {
  205. SurfaceFree(Ptr);
  206. return ERR_OUT_OF_MEMORY;
  207. }
  208. return ERR_NONE;
  209. }
  210. Ptr[0] = Alloc16(GetImageSize(p));
  211. return Ptr[0] ? ERR_NONE : ERR_OUT_OF_MEMORY;
  212. }
  213. void SurfaceFree(planes p)
  214. {
  215. int i;
  216. for (i=0;i<MAXPLANES;++i)
  217. {
  218. Free16(p[i]);
  219. p[i] = NULL;
  220. }
  221. }
  222. int DefaultAspect(int Width,int Height)
  223. {
  224. return ASPECT_ONE; //todo?
  225. }
  226. void DefaultPitch(video* p)
  227. {
  228. p->Pitch = p->Width*GetBPP(&p->Pixel);
  229. if (p->Pixel.Flags & PF_RGB) 
  230. p->Pitch = ((p->Pitch+31)>>5)*4; // dword align
  231. else 
  232. p->Pitch = (p->Pitch+7)>>3; // byte align
  233. }
  234. void DefaultRGB(pixel* p, int BitCount, 
  235.          int RBits, int GBits, int BBits,
  236.  int RGaps, int GGaps, int BGaps)
  237. {
  238. p->Flags = PF_RGB;
  239. p->BitCount = BitCount;
  240. p->BitMask[0] = ((1<<RBits)-1) << (RGaps+GBits+GGaps+BBits+BGaps);
  241. p->BitMask[1] = ((1<<GBits)-1) << (GGaps+BBits+BGaps);
  242. p->BitMask[2] = ((1<<BBits)-1) << (BGaps);
  243. }
  244. bool_t Compressed(const pixel* Fmt)
  245. {
  246. return (Fmt->Flags & PF_FOURCC) && !AnyYUV(Fmt);
  247. }
  248. bool_t PlanarYUV(const pixel* Fmt, int* x, int* y,int *s)
  249. {
  250. if (PlanarYUV420(Fmt))
  251. {
  252. if (x) *x = 1;
  253. if (y) *y = 1;
  254. if (s)
  255. {
  256. if (Fmt->Flags & PF_FOURCC &&
  257. ((Fmt->FourCC == FOURCC_IMC2) || (Fmt->FourCC == FOURCC_IMC4)))
  258. *s = 0; // interleaved uv scanlines
  259. else
  260. *s = 1;
  261. }
  262. return 1;
  263. }
  264. if (PlanarYUV422(Fmt))
  265. {
  266. if (x) *x = 1;
  267. if (s) *s = 1;
  268. if (y) *y = 0;
  269. return 1;
  270. }
  271. if (PlanarYUV444(Fmt))
  272. {
  273. if (x) *x = 0;
  274. if (y) *y = 0;
  275. if (s) *s = 0;
  276. return 1;
  277. }
  278. if (PlanarYUV410(Fmt))
  279. {
  280. if (x) *x = 2;
  281. if (s) *s = 2;
  282. if (y) *y = 2;
  283. return 1;
  284. }
  285. if (x) *x = 0;
  286. if (y) *y = 0;
  287. if (s) *s = 0;
  288. return 0;
  289. }
  290. typedef struct rgbfourcc
  291. {
  292. uint32_t FourCC;
  293. int BitCount;
  294. uint32_t BitMask[3];
  295. } rgbfourcc;
  296. static const rgbfourcc RGBFourCC[] =
  297. {
  298. { FOURCC_RGB32, 32, { 0xFF0000, 0xFF00, 0xFF }},
  299. { FOURCC_RGB24, 24, { 0xFF0000, 0xFF00, 0xFF }},
  300. { FOURCC_RGB16, 16, { 0xF800, 0x07E0, 0x001F }},
  301. { FOURCC_RGB15, 16, { 0x7C00, 0x03E0, 0x001F }},
  302. { FOURCC_BGR32, 32, { 0xFF, 0xFF00, 0xFF0000 }},
  303. { FOURCC_BGR24, 24, { 0xFF, 0xFF00, 0xFF0000 }},
  304. { FOURCC_BGR16, 16, { 0x001F, 0x07E0, 0xF800 }},
  305. { FOURCC_BGR15, 16, { 0x001F, 0x03E0, 0x7C00 }},
  306. {0},
  307. };
  308. uint32_t DefFourCC(const pixel* Fmt)
  309. {
  310. uint32_t FourCC=0;
  311. if (Fmt->Flags & PF_YUV420)
  312. return FOURCC_I420;
  313. if (Fmt->Flags & PF_YUV422)
  314. return FOURCC_YV16;
  315. if (Fmt->Flags & PF_YUV410)
  316. return FOURCC_YUV9;
  317. if (Fmt->Flags & PF_FOURCC)
  318. {
  319. FourCC = Fmt->FourCC;
  320. if (FourCC == FOURCC_YVU9)
  321. FourCC = FOURCC_YUV9;
  322. if (FourCC == FOURCC_IYUV || FourCC == FOURCC_YV12)
  323. FourCC = FOURCC_I420;
  324. if (FourCC == FOURCC_YUNV || FourCC == FOURCC_V422 || FourCC == FOURCC_YUYV)
  325. FourCC = FOURCC_YUY2;
  326. if (FourCC == FOURCC_Y422 || FourCC == FOURCC_UYNV)
  327. FourCC = FOURCC_UYVY;
  328. }
  329. else
  330. if (Fmt->Flags & PF_RGB)
  331. {
  332. const rgbfourcc *i;
  333. for (i=RGBFourCC;i->FourCC;++i)
  334. if (i->BitCount == Fmt->BitCount &&
  335. i->BitMask[0] == Fmt->BitMask[0] &&
  336. i->BitMask[1] == Fmt->BitMask[1] &&
  337. i->BitMask[2] == Fmt->BitMask[2])
  338. {
  339. FourCC = i->FourCC;
  340. break;
  341. }
  342. }
  343. return FourCC;
  344. }
  345. bool_t PlanarYUV420(const pixel* Fmt)
  346. {
  347. if (Fmt->Flags & PF_YUV420)
  348. return 1;
  349. return (Fmt->Flags & PF_FOURCC) && 
  350.      ((Fmt->FourCC == FOURCC_YV12) ||
  351.    (Fmt->FourCC == FOURCC_IYUV) ||
  352.    (Fmt->FourCC == FOURCC_I420) ||
  353.    (Fmt->FourCC == FOURCC_IMC2) ||
  354.    (Fmt->FourCC == FOURCC_IMC4));
  355. }
  356. bool_t PlanarYUV410(const pixel* Fmt)
  357. {
  358. if (Fmt->Flags & PF_YUV410)
  359. return 1;
  360. return (Fmt->Flags & PF_FOURCC) && 
  361.      ((Fmt->FourCC == FOURCC_YVU9) ||
  362.    (Fmt->FourCC == FOURCC_YUV9));
  363. }
  364. bool_t PlanarYUV422(const pixel* Fmt)
  365. {
  366. if (Fmt->Flags & PF_YUV422)
  367. return 1;
  368. return (Fmt->Flags & PF_FOURCC) && (Fmt->FourCC == FOURCC_YV16);
  369. }
  370. bool_t PlanarYUV444(const pixel* Fmt)
  371. {
  372. return (Fmt->Flags & PF_YUV444) != 0;
  373. }
  374. bool_t PackedYUV(const pixel* Fmt)
  375. {
  376. return (Fmt->Flags & PF_FOURCC) && 
  377.   ((Fmt->FourCC == FOURCC_YUY2) ||
  378.    (Fmt->FourCC == FOURCC_YUNV) ||
  379.    (Fmt->FourCC == FOURCC_V422) ||
  380.       (Fmt->FourCC == FOURCC_YUYV) ||
  381.    (Fmt->FourCC == FOURCC_VYUY) ||
  382.    (Fmt->FourCC == FOURCC_UYVY) ||
  383.    (Fmt->FourCC == FOURCC_Y422) ||
  384.    (Fmt->FourCC == FOURCC_YVYU) ||
  385.    (Fmt->FourCC == FOURCC_UYNV));
  386. }
  387. bool_t AnyYUV(const pixel* Fmt)
  388. {
  389. return PlanarYUV420(Fmt) || 
  390. PlanarYUV410(Fmt) || 
  391. PlanarYUV422(Fmt) || 
  392. PlanarYUV444(Fmt) || 
  393. PackedYUV(Fmt);
  394. }
  395. uint32_t RGBToFormat(rgbval_t RGB, const pixel* Fmt)
  396. {
  397. uint32_t v;
  398. int R,G,B;
  399. int Y,U,V;
  400. int Pos[3];
  401. R = (INT32LE(RGB) >> 0) & 255;
  402. G = (INT32LE(RGB) >> 8) & 255;
  403. B = (INT32LE(RGB) >> 16) & 255;
  404. if (AnyYUV(Fmt))
  405. {
  406. Y = ((2105 * R) + (4128 * G) + (802 * B))/0x2000 + 16;
  407. V = ((3596 * R) - (3015 * G) - (582 * B))/0x2000 + 128;
  408. U = (-(1212 * R) - (2384 * G) + (3596 * B))/0x2000 + 128;
  409. if (Fmt->Flags & PF_INVERTED)
  410. {
  411. Y ^= 255;
  412. U ^= 255;
  413. V ^= 255;
  414. }
  415. v =  (Fmt->BitMask[0] / 255) * Y;
  416. v += (Fmt->BitMask[1] / 255) * U;
  417. v += (Fmt->BitMask[2] / 255) * V;
  418. }
  419. else
  420. {
  421. if (Fmt->Flags & PF_INVERTED)
  422. {
  423. R ^= 255;
  424. G ^= 255;
  425. B ^= 255;
  426. }
  427. Pos[0] = BitMaskPos(Fmt->BitMask[0]) + BitMaskSize(Fmt->BitMask[0]);
  428. Pos[1] = BitMaskPos(Fmt->BitMask[1]) + BitMaskSize(Fmt->BitMask[1]);
  429. Pos[2] = BitMaskPos(Fmt->BitMask[2]) + BitMaskSize(Fmt->BitMask[2]);
  430. v = ((R << Pos[0]) & (Fmt->BitMask[0] << 8)) |
  431. ((G << Pos[1]) & (Fmt->BitMask[1] << 8)) |
  432. ((B << Pos[2]) & (Fmt->BitMask[2] << 8));
  433. v >>= 8;
  434. }
  435. return v;
  436. }
  437. void FillInfo(pixel* Fmt)
  438. {
  439. Fmt->BitCount = GetBPP(Fmt);
  440. if (PlanarYUV(Fmt,NULL,NULL,NULL))
  441. {
  442. if (Fmt->Flags & (PF_YUV420|PF_YUV422|PF_YUV444|PF_YUV410))
  443. {
  444. Fmt->BitMask[0] = 0x000000FF;
  445. Fmt->BitMask[1] = 0x0000FF00;
  446. Fmt->BitMask[2] = 0x00FF0000;
  447. }
  448. else
  449. switch (Fmt->FourCC)
  450. {
  451. case FOURCC_IMC4:
  452. case FOURCC_I420: 
  453. case FOURCC_IYUV:
  454. case FOURCC_YUV9:
  455. Fmt->BitMask[0] = 0x000000FF;
  456. Fmt->BitMask[1] = 0x0000FF00;
  457. Fmt->BitMask[2] = 0x00FF0000;
  458. break;
  459. case FOURCC_IMC2:
  460. case FOURCC_YV16:
  461. case FOURCC_YV12: 
  462. case FOURCC_YVU9:
  463. Fmt->BitMask[0] = 0x000000FF;
  464. Fmt->BitMask[1] = 0x00FF0000;
  465. Fmt->BitMask[2] = 0x0000FF00;
  466. break;
  467. }
  468. }
  469. else
  470. if (PackedYUV(Fmt))
  471. switch (Fmt->FourCC)
  472. {
  473. case FOURCC_YUY2:
  474. case FOURCC_YUNV:
  475. case FOURCC_V422:
  476. case FOURCC_YUYV:
  477. Fmt->BitMask[0] = 0x00FF00FF;
  478. Fmt->BitMask[1] = 0x0000FF00;
  479. Fmt->BitMask[2] = 0xFF000000;
  480. break;
  481. case FOURCC_YVYU:
  482. Fmt->BitMask[0] = 0x00FF00FF;
  483. Fmt->BitMask[1] = 0xFF000000;
  484. Fmt->BitMask[2] = 0x0000FF00;
  485. break;
  486. case FOURCC_UYVY:
  487. case FOURCC_Y422:
  488. case FOURCC_UYNV:
  489. Fmt->BitMask[0] = 0xFF00FF00;
  490. Fmt->BitMask[1] = 0x000000FF;
  491. Fmt->BitMask[2] = 0x00FF0000;
  492. break;
  493. }
  494. }
  495. int GetImageSize(const video* p)
  496. {
  497. int Size = p->Pitch * p->Height;
  498. if (PlanarYUV420(&p->Pixel))
  499. Size = (Size*3)/2; //1:0.25:0.25
  500. else
  501. if (PlanarYUV422(&p->Pixel))
  502. Size *= 2; //1:0.5:0.5
  503. else
  504. if (PlanarYUV444(&p->Pixel))
  505. Size *= 3; //1:1:1
  506. return Size;
  507. }
  508. int GetBPP(const pixel* Fmt)
  509. {
  510. if (Fmt->Flags & (PF_RGB | PF_PALETTE)) 
  511. return Fmt->BitCount;
  512. if (PlanarYUV(Fmt,NULL,NULL,NULL))
  513. return 8;
  514. if (PackedYUV(Fmt))
  515. return 16;
  516. return 0;
  517. }
  518. bool_t EqPoint(const point* a, const point* b)
  519. {
  520. return a->x==b->x && a->y==b->y;
  521. }
  522. bool_t EqRect(const rect* a, const rect* b)
  523. {
  524. return a->x==b->x && a->y==b->y && a->Width==b->Width && a->Height==b->Height;
  525. }
  526. bool_t EqPixel(const pixel* a, const pixel* b)
  527. {
  528. if (a->Flags != b->Flags) 
  529. return 0;
  530. if ((a->Flags & PF_PALETTE) &&
  531. a->BitCount != b->BitCount)
  532. return 0;
  533. if ((a->Flags & PF_RGB) &&
  534. (a->BitCount != b->BitCount ||
  535.  a->BitMask[0] != b->BitMask[0] ||
  536.  a->BitMask[1] != b->BitMask[1] ||
  537.  a->BitMask[2] != b->BitMask[2]))
  538. return 0;
  539. if ((a->Flags & PF_FOURCC) && a->FourCC != b->FourCC)
  540. return 0;
  541. return 1;
  542. }
  543. bool_t EqVideo(const video* a, const video* b)
  544. {
  545. // no direction check here!
  546. return a->Width == b->Width &&
  547.    a->Height == b->Height &&
  548.    a->Pitch == b->Pitch &&
  549.    EqPixel(&a->Pixel,&b->Pixel);
  550. }
  551. void ClipRectPhy(rect* Physical, const video* p)
  552. {
  553. if (Physical->x < 0)
  554. {
  555. Physical->Width += Physical->x;
  556. Physical->x = 0;
  557. }
  558. if (Physical->y < 0)
  559. {
  560. Physical->Height += Physical->y;
  561. Physical->y = 0;
  562. }
  563. if (Physical->x + Physical->Width > p->Width)
  564. {
  565. Physical->Width = p->Width - Physical->x;
  566. if (Physical->Width < 0)
  567. {
  568. Physical->Width = 0;
  569. Physical->x = 0;
  570. }
  571. }
  572. if (Physical->y + Physical->Height > p->Height)
  573. {
  574. Physical->Height = p->Height - Physical->y;
  575. if (Physical->Height < 0)
  576. {
  577. Physical->Height = 0;
  578. Physical->y = 0;
  579. }
  580. }
  581. }
  582. void VirtToPhy(const rect* Virtual, rect* Physical, const video* p)
  583. {
  584. if (Virtual)
  585. {
  586. *Physical = *Virtual;
  587. if (p->Pixel.Flags & PF_PIXELDOUBLE)
  588. {
  589. Physical->x >>= 1;
  590. Physical->y >>= 1;
  591. Physical->Width >>= 1;
  592. Physical->Height >>= 1;
  593. }
  594. if (p->Direction & DIR_SWAPXY)
  595. SwapRect(Physical);
  596. if (p->Direction & DIR_MIRRORLEFTRIGHT)
  597. Physical->x = p->Width - Physical->x - Physical->Width;
  598. if (p->Direction & DIR_MIRRORUPDOWN)
  599. Physical->y = p->Height - Physical->y - Physical->Height;
  600. ClipRectPhy(Physical,p);
  601. }
  602. else
  603. {
  604. Physical->x = 0;
  605. Physical->y = 0;
  606. Physical->Width = p->Width;
  607. Physical->Height = p->Height;
  608. }
  609. }
  610. void PhyToVirt(const rect* Physical, rect* Virtual, const video* p)
  611. {
  612. if (Physical)
  613. *Virtual = *Physical;
  614. else
  615. {
  616. Virtual->x = 0;
  617. Virtual->y = 0;
  618. Virtual->Width = p->Width;
  619. Virtual->Height = p->Height;
  620. }
  621. if (p->Direction & DIR_MIRRORLEFTRIGHT)
  622. Virtual->x = p->Width - Virtual->x - Virtual->Width;
  623. if (p->Direction & DIR_MIRRORUPDOWN)
  624. Virtual->y = p->Height - Virtual->y - Virtual->Height;
  625. if (p->Direction & DIR_SWAPXY)
  626. SwapRect(Virtual);
  627. if (p->Pixel.Flags & PF_PIXELDOUBLE)
  628. {
  629. Virtual->x <<= 1;
  630. Virtual->y <<= 1;
  631. Virtual->Width <<= 1;
  632. Virtual->Height <<= 1;
  633. }
  634. }