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

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: blit_arm_stretch.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. //todo: ReUse with OnlyDiff condition. optimize IncPtr (change to pre increment)
  24. #include "../common.h"
  25. #include "../dyncode/dyncode.h"
  26. #include "blit_soft.h"
  27. #if defined(ARM)
  28. typedef struct stack
  29. {
  30. int InvertMask;
  31. int DiffMask;
  32. int PalPtr;
  33. int EndOfLine;
  34. int EndOfRect;
  35. int DstPitch;
  36. int DstNext;
  37. int Y;
  38. int U;
  39. int V;
  40. int Pos;
  41. int SaveR7; //onlydifference && dither
  42. int SaveR8; //onlydifference && dither
  43. int StackFrame[STACKFRAME];
  44. //void* this   R0
  45. //char* Dst    R1
  46. //char* Src    R2
  47. //int DstPitch R3
  48. int SrcPitch;
  49. int Width; 
  50. int Height;
  51. int Src2SrcLast;
  52. } stack;
  53. // palette
  54. // 
  55. // R0 result RGB
  56. // R1..R3 R,G,B accumulator
  57. // R4..R6 temporary
  58. // R9 Dst
  59. // R7 U+UVNextRow (when SwapXY)
  60. // R8 V+UVNextRow (when SwapXY)
  61. // R10 U
  62. // R11 V
  63. // R12 Y
  64. // R14 Y+YNextRow (when SwapXY)
  65. static NOINLINE void Inc_RGB_UV_Pixel(blit_soft* p, int dY, int dUV)
  66. {
  67. bool_t NextRow = (p->SwapXY) && (p->Upper == (p->DirX>0));
  68. reg Y,V,U;
  69. Y = (reg)(NextRow ? R14:R12);
  70. V = (reg)(NextRow ? R8:R11);
  71. U = (reg)(NextRow ? R7:R10);
  72. if (dY) I2C(ADD,Y,Y,dY);
  73. if (dUV) I2C(ADD,U,U,dUV);
  74. if (dUV) I2C(ADD,V,V,dUV);
  75. }
  76. static NOINLINE void Add_RGB_UV_Pixel(blit_soft* p, int Amount, int dY, int dUV, bool_t IncPtr)
  77. {
  78. assert(Amount>0 || !IncPtr);
  79. if (Amount)
  80. {
  81. int Load = IncPtr ? LDR_POST : LDR;
  82. reg Y,V,U;
  83. bool_t NextRow = (p->SwapXY) && (p->Upper == (p->DirX>0));
  84. Y = (reg)(NextRow ? R14:R12);
  85. V = (reg)(NextRow ? R8:R11);
  86. U = (reg)(NextRow ? R7:R10);
  87. if (p->DstPalette)
  88. {
  89. Byte(); I2C(Load,R4,Y,dY);  //y
  90. Byte(); I2C(Load,R6,V,dUV); //v
  91. Byte(); I2C(Load,R5,U,dUV); //u
  92. }
  93. else
  94. {
  95. Byte(); I2C(Load,R4,Y,dY); //y
  96. IConst(R5,(p->_YMul >> 8) * Amount);
  97. Byte(); I2C(Load,R6,V,dUV); //v
  98. I4(MLA,R1,R5,R4,R1);
  99. I4(MLA,R2,R5,R4,R2);
  100. I4(MLA,R3,R5,R4,R3);
  101. Byte(); I2C(Load,R4,U,dUV); //u
  102. IConst(R5,(p->_GVMul >> 8) * Amount);
  103. I4(MLA,R2,R5,R6,R2);
  104. IConst(R5,(p->_RVMul >> 8) * Amount);
  105. I4(MLA,R1,R5,R6,R1);
  106. IConst(R5,(p->_GUMul >> 8) * Amount);
  107. I4(MLA,R2,R5,R4,R2);
  108. IConst(R5,(p->_BUMul >> 8) * Amount);
  109. I4(MLA,R3,R5,R4,R3);
  110. }
  111. }
  112. }
  113. static NOINLINE void Stretch_RGB_UV_Pixel(blit_soft* p, int Col, int dY, int dUV)
  114. {
  115. int SatBit = p->QAdd ? 32 : 24;
  116. int RPos = p->DstPos[0];
  117. int GPos = p->DstPos[1];
  118. int BPos = p->DstPos[2];
  119. if (p->Upper && p->DstBPP<=16)
  120. {
  121. RPos += p->DstBPP;
  122. GPos += p->DstBPP;
  123. BPos += p->DstBPP;
  124. }
  125. if (!p->DstPalette)
  126. {
  127. if (p->Dither)
  128. {
  129. IConst(R4,p->_RAdd);
  130. IConst(R5,p->_GAdd);
  131. IConst(R6,p->_BAdd);
  132. I3S(ADD,R1,R4,R1,LSR,32-SatBit+p->DstSize[0]);
  133. I3S(ADD,R2,R5,R2,LSR,32-SatBit+p->DstSize[1]);
  134. I3S(ADD,R3,R6,R3,LSR,32-SatBit+p->DstSize[2]);
  135. }
  136. else
  137. {
  138. IConst(R1,p->_RAdd);
  139. IConst(R2,p->_GAdd);
  140. IConst(R3,p->_BAdd);
  141. }
  142. }
  143. if (p->ArithStretch)
  144. {
  145. int x = Col * p->RScaleX;
  146. Add_RGB_UV_Pixel(p,16*(16-(x & 15)),dY,dUV,!p->OnlyDiff);
  147. if (!p->OnlyDiff)
  148. {
  149. dY = -dY;
  150. dUV = -dUV;
  151. }
  152. ++dY;
  153. if (((x >> 4)&1) || p->SrcUVX2==0) //need UV increment?
  154. ++dUV;
  155. Add_RGB_UV_Pixel(p,16*(x & 15),dY,dUV,0);
  156. }
  157. else
  158. Add_RGB_UV_Pixel(p,256,dY,dUV,!p->OnlyDiff);
  159. if (p->DstPalette)
  160. {
  161. if (p->Dither)
  162. {
  163. I3S(ADD,R1,R1,R4,ROR,0);
  164. I3S(ADD,R2,R2,R5,ROR,0);
  165. I3S(ADD,R2,R2,R6,ROR,16);
  166. I2C(AND,R4,R1,0x1E0);
  167. I2C(AND,R5,R2,0x1E0);
  168. I2C(AND,R6,R2,0x1E00000);
  169. I3S(ADD,R0,R3,R4,LSL,5);
  170. I3S(ADD,R0,R0,R5,LSL,1);
  171. I3S(ADD,R0,R0,R6,LSR,3+16);
  172. Byte(); I2C(LDR,R4,R0,1);
  173. Byte(); I2C(LDR,R5,R0,2);
  174. Byte(); I2C(LDR,R6,R0,3);
  175. Byte(); I2C(LDR,R0,R0,0);
  176. I3S(SUB,R1,R1,R4,ROR,0);
  177. I3S(SUB,R2,R2,R5,ROR,0);
  178. I3S(SUB,R2,R2,R6,ROR,16);
  179. }
  180. else
  181. {
  182. I2C(AND,R4,R4,0x1E0);
  183. I2C(AND,R5,R5,0x1E0);
  184. I2C(AND,R6,R6,0x1E0);
  185. I3S(ADD,R0,R3,R4,LSL,5);
  186. I3S(ADD,R0,R0,R5,LSL,1);
  187. I3S(ADD,R0,R0,R6,LSR,3);
  188. Byte(); I2C(LDR,R0,R0,0);
  189. }
  190. p->Pos = 0;
  191. }
  192. else
  193. {
  194. if (p->QAdd)
  195. {
  196. I3(QDADD,R1,R1,R1);
  197. I3(QDADD,R2,R2,R2);
  198. I3(QDADD,R3,R3,R3);
  199. }
  200. else
  201. {
  202. I2C(TST,NONE,R1,0xFF000000);
  203. C(NE);I2C(MVN,R1,NONE,0xFF000000);
  204. C(MI);I2C(MOV,R1,NONE,0x00000000);
  205. I2C(TST,NONE,R2,0xFF000000);
  206. C(NE);I2C(MVN,R2,NONE,0xFF000000);
  207. C(MI);I2C(MOV,R2,NONE,0x00000000);
  208. I2C(TST,NONE,R3,0xFF000000);
  209. C(NE);I2C(MVN,R3,NONE,0xFF000000);
  210. C(MI);I2C(MOV,R3,NONE,0x00000000);
  211. }
  212. if (p->InvertMask && p->Pos<0)
  213. {
  214. p->Pos = RPos;
  215. MB(); I2C(LDR,R0,SP,OFS(stack,InvertMask));
  216. }
  217. if (p->Pos!=RPos && p->Pos>=0) I3S(MOV,R0,NONE,R0,ROR,RPos-p->Pos);
  218. I3S(p->Pos<0?MOV:EOR,R0,(reg)(p->Pos<0?NONE:R0),R1,LSR,SatBit-p->DstSize[0]);
  219. I3S(MOV,R4,NONE,R2,LSR,SatBit-p->DstSize[1]);
  220. I3S(MOV,R0,NONE,R0,ROR,BPos-RPos);
  221. I3S(EOR,R0,R0,R4,ROR,BPos-GPos);
  222. I3S(EOR,R0,R0,R3,LSR,SatBit-p->DstSize[2]);
  223. p->Pos = BPos;
  224. if (p->Dither)
  225. {
  226. MB(); I3S(MOV,R1,NONE,R1,LSL,32-SatBit+p->DstSize[0]);
  227. MB(); I3S(MOV,R2,NONE,R2,LSL,32-SatBit+p->DstSize[1]);
  228. MB(); I3S(MOV,R3,NONE,R3,LSL,32-SatBit+p->DstSize[2]);
  229. }
  230. }
  231. }
  232. void Stretch_RGB_UV(blit_soft* p)
  233. {
  234. bool_t Special;
  235. dyninst* LoopX;
  236. dyninst* LoopY;
  237. dyninst* EndOfLine;
  238. int i,Col,ColCount,RowStep;
  239. int Mask = 0;
  240. int Invert = 0;
  241. bool_t ReUse;
  242. bool_t NoInc;
  243. bool_t RegDirty; //R4,R5
  244. p->Dither = (boolmem_t)((p->DstBPP<=16) && (p->FX.Flags & BLITFX_DITHER)!=0);
  245. p->DstStepX = p->DirX * ((p->DstBPP*2) >> 3);
  246. p->PalPtr = NULL;
  247. p->DiffMask = NULL;
  248. p->InvertMask = NULL;
  249. if (p->Dst.Flags & PF_INVERTED)
  250. Invert = -1;
  251. CodeBegin();
  252. I2C(SUB,SP,SP,OFS(stack,StackFrame));
  253. I2C(LDR,R9,R1,0);  //Dst[0] RGB
  254. I2C(LDR,R10,R2,4); //Src[1] U
  255. I2C(LDR,R11,R2,8); //Src[2] V
  256. I2C(LDR,R12,R2,0); //Src[0] Y
  257. I2C(STR,R10,SP,OFS(stack,U));
  258. I2C(STR,R11,SP,OFS(stack,V));
  259. I2C(STR,R12,SP,OFS(stack,Y));
  260. ReUse = p->RScaleX<16 && !Invert && !p->OnlyDiff && (!p->OnlyDiff || !p->SwapXY) && (!p->DstPalette || !p->SwapXY) && !p->ArithStretch; //R0 is saved in loop and not ArithStretch
  261. if (p->QAdd && ReUse && !p->SwapXY)
  262. {
  263. p->QAdd = 0; // invert not supported with ReUse
  264. CalcColor(p);
  265. }
  266. if (p->QAdd)
  267. {
  268. int Mask2,Shift,i;
  269. for (i=0;i<3;++i)
  270. Mask |= 1 << (p->DstPos[i] + p->DstSize[i] - 1);
  271. Mask2 = Mask;
  272. Shift = 0;
  273. if (p->DstBPP <= 16)
  274. {
  275. if (p->DirX<0) Shift = p->DstBPP;
  276. Mask2 |= Mask << p->DstBPP;
  277. }
  278. Invert ^= RotateRight(Mask2,Shift+p->DstPos[0]);
  279. }
  280. if (Invert)
  281. {
  282. p->InvertMask = InstCreate32(Invert,NONE,NONE,NONE,0,0);
  283. MB(); I1P(LDR,R5,p->InvertMask,0);
  284. I2C(STR,R5,SP,OFS(stack,InvertMask));
  285. }
  286. if (p->OnlyDiff)
  287. {
  288. p->DiffMask = InstCreate32(0xFCFCFCFC,NONE,NONE,NONE,0,0);
  289. MB(); I1P(LDR,R4,p->DiffMask,0);
  290. I2C(STR,R4,SP,OFS(stack,DiffMask));
  291. }
  292. I2C(STR,R3,SP,OFS(stack,DstPitch));
  293. I3(MOV,R6,NONE,R3); //DstPitch
  294. I2C(LDR,R7,SP,OFS(stack,SrcPitch));
  295. I2C(LDR,R0,SP,OFS(stack,Height));
  296. I2C(LDR,R4,SP,OFS(stack,Width));
  297. if (p->DirX<0 && p->DstBPP==16) //adjust reversed destination for block size
  298. I2C(SUB,R9,R9,-p->DstStepX-(p->DstBPP >> 3));
  299. if ((p->DstPalette || p->DstBPP==32) && p->SwapXY)
  300. I2C(ADD,R9,R9,p->DstStepX/2);
  301. if (p->SwapXY)
  302. {
  303. I2C(MOV,R1,NONE,p->DstBPP * p->DirX);
  304. I3(MUL,R0,R1,R0);
  305. I3S(ADD,R0,R9,R0,ASR,3);
  306. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  307. //DstNext = DstStepX - Width*DstPitch;
  308. MB(); I3(MUL,R2,R6,R4);
  309. I2C(MOV,R0,NONE,p->DstStepX);
  310. I3(SUB,R0,R0,R2); 
  311. I2C(STR,R0,SP,OFS(stack,DstNext));
  312. }
  313. else
  314. {
  315. I3(MUL,R0,R6,R0); //DstPitch * Height
  316. I3(ADD,R0,R9,R0);
  317. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  318. //DstNext = DstPitch - DirX * Width << DstBPP2;
  319. I3S(p->DirX>0?SUB:ADD,R2,R6,R4,LSL,p->DstBPP2); 
  320. I2C(STR,R2,SP,OFS(stack,DstNext));
  321. }
  322. if (p->Dst.Flags & PF_PALETTE)
  323. {
  324. p->PalPtr = InstCreate32((int)p->LookUp_Data,NONE,NONE,NONE,0,0);
  325. MB(); I1P(LDR,R3,p->PalPtr,0);
  326. if (p->Dither)
  327. {
  328. I2C(MOV,R1,NONE,0);
  329. I2C(MOV,R2,NONE,0);
  330. }
  331. }
  332. else
  333. {
  334. if (p->Dither)
  335. {
  336. I2C(MVN,R1,NONE,0x80000000);
  337. I2C(MVN,R2,NONE,0x80000000);
  338. I2C(MVN,R3,NONE,0x80000000);
  339. }
  340. }
  341. I2C(MOV,R5,NONE,0); //Pos
  342. LoopY = Label(0);
  343. I0P(B,AL,LoopY);
  344. if (p->InvertMask) InstPost(p->InvertMask);
  345. if (p->DiffMask) InstPost(p->DiffMask);
  346. if (p->PalPtr) InstPost(p->PalPtr);
  347. ColCount = 32;
  348. for (i=1;i<16 && !(p->RScaleX & i);i<<=1)
  349. ColCount >>= 1;
  350. InstPost(LoopY);
  351. EndOfLine = Label(0);
  352. //R4 Width
  353. //R5 Pos
  354. //R7 SrcPitch
  355. if (p->SwapXY)
  356. {
  357. I3(MUL,R4,R6,R4); //R6=DstPitch
  358. I3(ADD,R4,R9,R4);
  359. }
  360. else
  361. {
  362. if (p->DirX > 0)
  363. I3S(ADD,R4,R9,R4,LSL,p->DstBPP2);
  364. else
  365. I3S(SUB,R4,R9,R4,LSL,p->DstBPP2);
  366. }
  367. I2C(STR,R4,SP,OFS(stack,EndOfLine));
  368. if (p->SwapXY)
  369. {
  370. //we need next row in R14,R7,R8 (YUV)
  371. IMul(R6,R5,p->RScaleY); //R6 = RScaleY*Pos
  372. I2C(ADD,R8,R6,p->RScaleY);//R8 = RScaleY*(Pos+1)
  373. // dY  = ((RScaleY * (Pos+1)) >> 4) - ((RScaleY * Pos) >> 4);
  374. I3S(MOV,R14,NONE,R8,LSR,4);
  375. I3S(SUB,R14,R14,R6,LSR,4);
  376. I3(MUL,R14,R7,R14);
  377. // dUV = ((RScaleY * (Pos+1)) >> (4+SrcUVY2)) - ((RScaleY * Pos) >> (4+SrcUVY2));
  378. I3S(MOV,R8,NONE,R8,LSR,4+p->SrcUVY2);
  379. I3S(SUB,R8,R8,R6,LSR,4+p->SrcUVY2);
  380. I3(MUL,R8,R7,R8);
  381. I3(ADD,R14,R12,R14);
  382. I3S(ADD,R7,R10,R8,ASR,p->SrcUVX2);
  383. I3S(ADD,R8,R11,R8,ASR,p->SrcUVX2);
  384. }
  385. I2C(STR,R5,SP,OFS(stack,Pos));
  386. // special case, when R7,R8 must be saved/restored and incremented separatly
  387. Special = p->OnlyDiff && (p->Dither) && (p->SwapXY);
  388. if (Special)
  389. {
  390. I2C(STR,R7,SP,OFS(stack,SaveR7));
  391. I2C(STR,R8,SP,OFS(stack,SaveR8));
  392. }
  393. if (p->OnlyDiff)
  394. {
  395. MB(); I2C(LDR,R5,SP,OFS(stack,DiffMask));
  396. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  397. }
  398. LoopX = Label(1);
  399. RegDirty = 1;
  400. NoInc = 0;
  401. for (Col=0;Col<ColCount;)
  402. {
  403. int x = (Col * p->RScaleX) >> 4;
  404. int IncY;
  405. int IncUV;
  406. int IncY2 = 0;
  407. int IncUV2 = 0;
  408. int Col1 = Col;
  409. int Col2 = Col;
  410. IncY = (((Col+1) * p->RScaleX) >> 4) - ((Col * p->RScaleX) >> 4);
  411. IncUV = (((Col+1) * p->RScaleX) >> (4+p->SrcUVX2)) - ((Col * p->RScaleX) >> (4+p->SrcUVX2));
  412. Col++;
  413. if (!(p->SwapXY))
  414. {
  415. IncY2 = (((Col+1) * p->RScaleX) >> 4) - ((Col * p->RScaleX) >> 4);
  416. IncUV2 = (((Col+1) * p->RScaleX) >> (4+p->SrcUVX2)) - ((Col * p->RScaleX) >> (4+p->SrcUVX2));
  417. Col2++;
  418. Col++;
  419. }
  420. else
  421. if (!p->OnlyDiff)
  422. {
  423. IncY2 = IncY;
  424. IncUV2 = IncUV;
  425. }
  426. if (p->OnlyDiff)
  427. {
  428. reg RC = (reg)(p->SwapXY ? R0 : R14);
  429. reg RA = (reg)(p->Dither ? R7 : R1);
  430. reg RB = (reg)(p->Dither ? R8 : R2);
  431. RegDirty = 1;
  432. p->Skip = Label(0);
  433. //RC,RA,RB,R4 for temporary
  434. //R5(DiffMask),R6(Src2SrcLast)
  435. if (p->SwapXY)
  436. {
  437. Byte(); I3(LDR,RC,R12,R6);
  438. Byte(); I2C(LDR_POST,RA,R12,IncY);
  439. Byte(); I3(LDR,R4,R14,R6);
  440. Byte(); I2C(LDR_POST,RB,R14,IncY);
  441. IncY = IncY2 = -IncY;
  442. }
  443. else
  444. {
  445. Byte(); I3(LDR,RC,R12,R6);
  446. Byte(); I2C(LDR_POST,RA,R12,IncY);
  447. Byte(); I3(LDR,R4,R12,R6);
  448. Byte(); I2C(LDR_POST,RB,R12,IncY2);
  449. IncY = -IncY-IncY2;
  450. IncY2 = -IncY2;
  451. }
  452. I3(EOR,RC,RC,RA);
  453. S(); I3(TST,NONE,RC,R5);
  454. I3(EOR,R4,R4,RB);
  455. C(EQ); S(); I3(TST,NONE,R4,R5);
  456. C(EQ); Byte(); I3(LDR,RC,R10,R6); //last u
  457. Byte(); I2C(LDR_POST,RA,R10,IncUV+IncUV2); //u
  458. C(EQ); Byte(); I3(LDR,R4,R11,R6); //last v
  459. Byte(); I2C(LDR_POST,RB,R11,IncUV+IncUV2); //v
  460. IncUV = -IncUV-IncUV2;
  461. if (Special) //R7,R8 not incremented, using direct position
  462. IncUV2 = x >> p->SrcUVX2;
  463. else
  464. if (p->SwapXY) //IncUV2 will increment R7,R8
  465. {
  466. I2C(ADD,R7,R7,-IncUV);
  467. I2C(ADD,R8,R8,-IncUV);
  468. IncUV2 = IncUV;
  469. }
  470. else
  471. IncUV2 = -IncUV2;
  472. C(EQ); I3(EOR,RC,RC,RA);
  473. C(EQ); S(); I3(TST,NONE,RC,R5);
  474. C(EQ); I3(EOR,R4,R4,RB);
  475. C(EQ); S(); I3(TST,NONE,R4,R5);
  476. C(EQ); I2C(LDR,R4,SP,OFS(stack,EndOfLine));
  477. #ifdef SHOWDIFF
  478. I2C(MVN,RC,NONE,0);
  479. if (DstBPP==8) Half();
  480. C(EQ); I2(STR,RC,R9);
  481. #endif
  482. if (p->SwapXY)
  483. {
  484. MB(); I2C(LDR,RC,SP,OFS(stack,DstPitch));
  485. C(EQ); I3(ADD,R9,R9,RC);
  486. }
  487. else
  488. {
  489. C(EQ); I2C(ADD,R9,R9,p->DstStepX);
  490. }
  491. I0P(B,EQ,p->Skip);
  492. if (Special)
  493. {
  494. I2C(LDR,R7,SP,OFS(stack,SaveR7));
  495. I2C(LDR,R8,SP,OFS(stack,SaveR8));
  496. }
  497. }
  498. p->Upper = p->DirX < 0;
  499. if (ReUse && NoInc)
  500. {
  501. p->Pos = 0;
  502. if (!p->SwapXY && p->DstBPP==16)
  503. I3S(MOV,R0,NONE,R0,LSL,p->Upper?16:-16);
  504. if (!p->OnlyDiff)
  505. Inc_RGB_UV_Pixel(p, IncY, IncUV);
  506. }
  507. else
  508. {
  509. p->Pos = -1;
  510. Stretch_RGB_UV_Pixel(p, Col1, IncY, IncUV);
  511. RegDirty = 1;
  512. }
  513. if (!p->SwapXY) 
  514. NoInc = !IncY && !IncUV;
  515. if (p->DstPalette)
  516. Byte();
  517. if (p->DstPalette || p->DstBPP==32)
  518. {
  519. if (p->DstBPP==32 && p->Pos)
  520. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  521. if (p->SwapXY)
  522. I2C(STR,R0,R9,-p->DstStepX/2);
  523. else
  524. I2C(STR_POST,R0,R9,p->DstStepX/2);
  525. }
  526. p->Upper = p->DirX > 0;
  527. if (ReUse && NoInc)
  528. {
  529. if (!p->SwapXY && p->DstBPP==16)
  530. I3S(ORR,R0,R0,R0,ROR,16);
  531. if (!p->OnlyDiff)
  532. Inc_RGB_UV_Pixel(p, IncY2, IncUV2);
  533. }
  534. else
  535. {
  536. if (p->DstBPP!=16)
  537. p->Pos = -1;
  538. Stretch_RGB_UV_Pixel(p, Col2, IncY2, IncUV2);
  539. RegDirty = 1;
  540. }
  541. if (!p->SwapXY) 
  542. NoInc = !IncY2 && !IncUV2;
  543. else
  544. NoInc = !IncY && !IncUV;
  545. if (p->Pos) 
  546. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  547. if (p->DstPalette || p->DstBPP==32)
  548. {
  549. if (p->SwapXY)
  550. {
  551. if (RegDirty) { MB(); I2C(LDR,R5,SP,OFS(stack,DstPitch)); }
  552. if (p->DstPalette) Byte(); 
  553. I3(STR_POST,R0,R9,R5);
  554. }
  555. else
  556. {
  557. if (p->DstPalette) Byte(); 
  558. I2C(STR_POST,R0,R9,p->DstStepX/2);
  559. }
  560. }
  561. else
  562. {
  563. if (p->SwapXY)
  564. {
  565. if (RegDirty) { MB(); I2C(LDR,R5,SP,OFS(stack,DstPitch)); }
  566. I3(STR_POST,R0,R9,R5);
  567. }
  568. else
  569. I2C(STR_POST,R0,R9,p->DstStepX);
  570. }
  571. if (RegDirty) { MB(); I2C(LDR,R4,SP,OFS(stack,EndOfLine)); }
  572. RegDirty = 0;
  573. if (p->OnlyDiff)
  574. {
  575. MB(); I2C(LDR,R5,SP,OFS(stack,DiffMask));
  576. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  577. InstPost(p->Skip);
  578. }
  579. I3(CMP,NONE,R9,R4);
  580. if (Col == ColCount) 
  581. {
  582. //last item in block
  583. if (Special) 
  584. {
  585. I2C(LDR,R7,SP,OFS(stack,SaveR7));
  586. I2C(LDR,R8,SP,OFS(stack,SaveR8));
  587. I2C(ADD,R7,R7,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  588. I2C(ADD,R8,R8,(p->RScaleX * ColCount) >> (4+p->SrcUVX2));
  589. I2C(STR,R7,SP,OFS(stack,SaveR7));
  590. I2C(STR,R8,SP,OFS(stack,SaveR8));
  591. }
  592. I0P(B,NE,LoopX);
  593. }
  594. else
  595. I0P(B,EQ,EndOfLine);
  596. }
  597. InstPost(EndOfLine);
  598. I2C(LDR,R6,SP,OFS(stack,DstNext));
  599. I2C(LDR,R7,SP,OFS(stack,SrcPitch));
  600. I2C(LDR,R5,SP,OFS(stack,Pos));
  601. I2C(LDR,R12,SP,OFS(stack,Y));
  602. I2C(LDR,R10,SP,OFS(stack,U));
  603. I2C(LDR,R11,SP,OFS(stack,V));
  604. I3(ADD,R9,R9,R6);
  605. //increment row of Y,U,V according to Pos -> Pos+RowStep
  606. RowStep = (p->SwapXY) ? 2:1;
  607. //R4,R6,R8 for temporary
  608. IMul(R6,R5,p->RScaleY); //R6 = RScaleY*Pos
  609. I2C(ADD,R5,R5,RowStep);
  610. IMul(R8,R5,p->RScaleY); //R8 = RScaleY*(Pos+RowStep)
  611. // dY  = ((RScaleY * (Pos+RowStep)) >> 4) - ((RScaleY * Pos) >> 4);
  612. I3S(MOV,R4,NONE,R8,LSR,4);
  613. I3S(SUB,R4,R4,R6,LSR,4);
  614. I3(MUL,R4,R7,R4);
  615. // dUV = ((RScaleY * (Pos+RowStep)) >> (4+SrcUVY2)) - ((RScaleY * Pos) >> (4+SrcUVY2));
  616. I3S(MOV,R8,NONE,R8,LSR,4+p->SrcUVY2);
  617. I3S(SUB,R8,R8,R6,LSR,4+p->SrcUVY2);
  618. I3(MUL,R8,R7,R8);
  619. I3(ADD,R12,R12,R4);
  620. I3S(ADD,R10,R10,R8,ASR,p->SrcUVPitch2); 
  621. I3S(ADD,R11,R11,R8,ASR,p->SrcUVPitch2);
  622. I2C(STR,R12,SP,OFS(stack,Y));
  623. I2C(STR,R10,SP,OFS(stack,U));
  624. I2C(STR,R11,SP,OFS(stack,V));
  625. //prepare registers for next row
  626. if (p->SwapXY) I2C(LDR,R6,SP,OFS(stack,DstPitch));
  627. I2C(LDR,R4,SP,OFS(stack,Width));
  628. MB(); I2C(LDR,R0,SP,OFS(stack,EndOfRect));
  629. I3(CMP,NONE,R9,R0);
  630. I0P(B,NE,LoopY);
  631. I2C(ADD,SP,SP,OFS(stack,StackFrame));
  632. CodeEnd();
  633. }
  634. #endif