scale.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496
  1. /****************************************************************************
  2. *
  3. * Module Title : scale.c
  4. *
  5. * Description : Image scaling functions.
  6. *
  7. ***************************************************************************/
  8. /****************************************************************************
  9. * Header Files
  10. ****************************************************************************/
  11. #include "postp.h"
  12. /****************************************************************************
  13. * Imports
  14. ****************************************************************************/
  15. extern void UpdateUMVBorder ( POSTPROC_INSTANCE *ppi, UINT8 * DestReconPtr );
  16. /****************************************************************************
  17. *
  18. * ROUTINE : HorizontalLine_Copy
  19. *
  20. * INPUTS : const unsigned char *source : Pointer to source data.
  21. * unsigned int sourceWidth : Stride of source.
  22. * unsigned char *dest : Pointer to destination data.
  23. * unsigned int destWidth : Stride of destination (NOT USED).
  24. *
  25. * OUTPUTS : None.
  26. *
  27. * RETURNS : void
  28. *
  29. * FUNCTION : Copies horizontal line of pixels from source to
  30. * destination unscaled.
  31. *
  32. * SPECIAL NOTES : None.
  33. *
  34. ****************************************************************************/
  35. void HorizontalLine_Copy
  36. (
  37. const unsigned char *source,
  38. unsigned int sourceWidth,
  39. unsigned char *dest,
  40. unsigned int destWidth
  41. )
  42. {
  43. (void) destWidth;
  44. memcpy ( dest, source, sourceWidth );
  45. }
  46. /****************************************************************************
  47. *
  48. * ROUTINE : NullScale
  49. *
  50. * INPUTS : unsigned char *dest : Pointer to destination data (NOT USED).
  51. * unsigned int destPitch : Stride of destination data (NOT USED).
  52. * unsigned int destWidth : Width of destination data (NOT USED).
  53. *
  54. * OUTPUTS : None.
  55. *
  56. * RETURNS : void
  57. *
  58. * FUNCTION : Null scaling function -- does nothing.
  59. *
  60. * SPECIAL NOTES : None.
  61. *
  62. ****************************************************************************/
  63. void NullScale ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  64. {
  65. (void) destWidth;
  66. (void) destPitch;
  67. (void) dest;
  68. return;
  69. }
  70. /****************************************************************************
  71. *
  72. * ROUTINE : HorizontalLine_4_5_Scale_C
  73. *
  74. * INPUTS : const unsigned char *source : Pointer to source data.
  75. * unsigned int sourceWidth : Stride of source.
  76. * unsigned char *dest : Pointer to destination data.
  77. * unsigned int destWidth : Stride of destination (NOT USED).
  78. *
  79. * OUTPUTS : None.
  80. *
  81. * RETURNS : void
  82. *
  83. * FUNCTION : Copies horizontal line of pixels from source to
  84. * destination scaling up by 4 to 5.
  85. *
  86. * SPECIAL NOTES : None.
  87. *
  88. ****************************************************************************/
  89. void HorizontalLine_4_5_Scale_C
  90. (
  91. const unsigned char *source,
  92. unsigned int sourceWidth,
  93. unsigned char *dest,
  94. unsigned int destWidth
  95. )
  96. {
  97. unsigned i;
  98. unsigned int a, b, c;
  99. unsigned char *des = dest;
  100. const unsigned char *src = source;
  101. (void) destWidth;
  102. for ( i=0; i<sourceWidth-4; i+=4 )
  103. {
  104. a = src[0];
  105. b = src[1];
  106. des [0] = (UINT8) a;
  107. des [1] = (UINT8) (( a * 51 + 205 * b + 128) >> 8);
  108. c = src[2] * 154;
  109. a = src[3];
  110. des [2] = (UINT8) (( b * 102 + c + 128) >> 8);
  111. des [3] = (UINT8) (( c + 102 * a + 128) >> 8);
  112. b = src[4];
  113. des [4] = (UINT8) (( a * 205 + 51 * b + 128) >> 8);
  114. src += 4;
  115. des += 5;
  116. }
  117. a = src[0];
  118. b = src[1];
  119. des [0] = (UINT8) (a);
  120. des [1] = (UINT8) (( a * 51 + 205 * b + 128) >> 8);
  121. c = src[2] * 154;
  122. a = src[3];
  123. des [2] = (UINT8) (( b * 102 + c + 128) >> 8);
  124. des [3] = (UINT8) (( c + 102 * a + 128) >> 8);
  125. des [4] = (UINT8) (a);
  126. }
  127. /****************************************************************************
  128. *
  129. * ROUTINE : VerticalBand_4_5_Scale_C
  130. *
  131. * INPUTS : unsigned char *dest : Pointer to destination data.
  132. * unsigned int destPitch : Stride of destination data.
  133. * unsigned int destWidth : Width of destination data.
  134. *
  135. * OUTPUTS : None.
  136. *
  137. * RETURNS : void
  138. *
  139. * FUNCTION : Scales vertical band of pixels by scale 4 to 5. The
  140. * height of the band scaled is 4-pixels.
  141. *
  142. * SPECIAL NOTES : The routine uses the first line of the band below
  143. * the current band.
  144. *
  145. ****************************************************************************/
  146. void VerticalBand_4_5_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  147. {
  148. unsigned int i;
  149. unsigned int a, b, c, d;
  150. unsigned char *des = dest;
  151. for ( i=0; i<destWidth; i++ )
  152. {
  153. a = des [0];
  154. b = des [destPitch];
  155. des[destPitch] = (UINT8) (( a * 51 + 205 * b + 128)>>8);
  156. c = des[destPitch*2]*154;
  157. d = des[destPitch*3];
  158. des [destPitch*2] = (UINT8) (( b * 102 + c + 128) >> 8);
  159. des [destPitch*3] = (UINT8) (( c + 102 * d + 128) >> 8);
  160. // First line in next band
  161. a = des [destPitch * 5];
  162. des [destPitch * 4] = (UINT8) (( d * 205 + 51 * a +128)>>8);
  163. des ++;
  164. }
  165. }
  166. /****************************************************************************
  167. *
  168. * ROUTINE : LastVerticalBand_4_5_Scale_C
  169. *
  170. * INPUTS : unsigned char *dest : Pointer to destination data.
  171. * unsigned int destPitch : Stride of destination data.
  172. * unsigned int destWidth : Width of destination data.
  173. *
  174. * OUTPUTS : None.
  175. *
  176. * RETURNS : void
  177. *
  178. * FUNCTION : Scales last vertical band of pixels by scale 4 to 5. The
  179. * height of the band scaled is 4-pixels.
  180. *
  181. * SPECIAL NOTES : The routine does not have available the first line of
  182. * the band below the current band, since this is the
  183. * last band.
  184. *
  185. ****************************************************************************/
  186. void LastVerticalBand_4_5_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  187. {
  188. unsigned int i;
  189. unsigned int a, b, c, d;
  190. unsigned char *des = dest;
  191. for ( i=0; i<destWidth; ++i )
  192. {
  193. a = des[0];
  194. b = des[destPitch];
  195. des[destPitch] = (UINT8) ((a * 51 + 205 * b + 128)>>8);
  196. c = des[destPitch*2]*154;
  197. d = des[destPitch*3];
  198. des [destPitch*2] = (UINT8) (( b * 102 + c + 128) >> 8);
  199. des [destPitch*3] = (UINT8) (( c + 102 * d + 128) >> 8);
  200. // No other line for interplation of this line, so ..
  201. des[destPitch*4] = (UINT8) d;
  202. des++;
  203. }
  204. }
  205. /****************************************************************************
  206. *
  207. * ROUTINE : Scale _4_5_2D
  208. *
  209. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  210. * const unsigned char *source : Pointer to source image.
  211. * unsigned int sourcePitch : Stride of source image.
  212. * unsigned int sourceWidth : Width of source image.
  213. * unsigned int sourceHeight : Height of source image (NOT USED).
  214. * unsigned char *dest : Pointer to destination image.
  215. * unsigned int destPitch : Stride of destination image.
  216. * unsigned int destWidth : Width of destination image.
  217. * unsigned int destHeight : Height of destination image.
  218. *
  219. * OUTPUTS : None.
  220. *
  221. * RETURNS : void
  222. *
  223. * FUNCTION : Two-dimensional 4 to 5 scaling up of an image.
  224. *
  225. * SPECIAL NOTES : None.
  226. *
  227. ****************************************************************************/
  228. void Scale_4_5_2D
  229. (
  230. POSTPROC_INSTANCE *ppi,
  231. const unsigned char *source,
  232. unsigned int sourcePitch,
  233. unsigned int sourceWidth,
  234. unsigned int sourceHeight,
  235. unsigned char *dest,
  236. unsigned int destPitch,
  237. unsigned int destWidth,
  238. unsigned int destHeight
  239. )
  240. {
  241. unsigned i, k;
  242. const unsigned int srcBandHeight = 4;
  243. const unsigned int destBandHeight = 5;
  244. (void) sourceHeight;
  245. (void) ppi;
  246. HorizontalLine_4_5_Scale ( source, sourceWidth, dest, destWidth );
  247. // Except last band
  248. for ( k=0; k<destHeight/destBandHeight-1; k++ )
  249. {
  250. // scale one band horizontally
  251. for ( i=1; i<srcBandHeight; i++ )
  252. {
  253. HorizontalLine_4_5_Scale ( source+i*sourcePitch,
  254. sourceWidth,
  255. dest+i*destPitch,
  256. destWidth);
  257. }
  258. // first line of next band
  259. HorizontalLine_4_5_Scale ( source+srcBandHeight*sourcePitch,
  260. sourceWidth,
  261. dest+destBandHeight*destPitch,
  262. destWidth );
  263. // Vertical scaling is in place
  264. VerticalBand_4_5_Scale ( dest, destPitch, destWidth );
  265. // move to the next band
  266. source += srcBandHeight * sourcePitch;
  267. dest += destBandHeight * destPitch;
  268. }
  269. // scale one band horizontally
  270. for ( i=1; i<srcBandHeight; i++ )
  271. {
  272. HorizontalLine_4_5_Scale ( source+i*sourcePitch,
  273. sourceWidth,
  274. dest+i*destPitch,
  275. destWidth );
  276. }
  277. // Vertical scaling is in place
  278. LastVerticalBand_4_5_Scale ( dest, destPitch, destWidth );
  279. }
  280. /****************************************************************************
  281. *
  282. * ROUTINE : HorizontalLine_3_5_Scale_C
  283. *
  284. * INPUTS : const unsigned char *source : Pointer to source data.
  285. * unsigned int sourceWidth : Stride of source.
  286. * unsigned char *dest : Pointer to destination data.
  287. * unsigned int destWidth : Stride of destination (NOT USED).
  288. *
  289. * OUTPUTS : None.
  290. *
  291. * RETURNS : void
  292. *
  293. * FUNCTION : Copies horizontal line of pixels from source to
  294. * destination scaling up by 3 to 5.
  295. *
  296. * SPECIAL NOTES : None.
  297. *
  298. *
  299. ****************************************************************************/
  300. void HorizontalLine_3_5_Scale_C
  301. (
  302. const unsigned char *source,
  303. unsigned int sourceWidth,
  304. unsigned char *dest,
  305. unsigned int destWidth
  306. )
  307. {
  308. unsigned int i;
  309. unsigned int a, b, c;
  310. unsigned char *des = dest;
  311. const unsigned char *src = source;
  312. (void) destWidth;
  313. for ( i=0; i<sourceWidth-3; i+=3 )
  314. {
  315. a = src[0];
  316. b = src[1];
  317. des [0] = (UINT8) (a);
  318. des [1] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
  319. c = src[2] ;
  320. des [2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
  321. des [3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
  322. a = src[3];
  323. des [4] = (UINT8) (( c * 154 + a * 102 + 128 ) >> 8);
  324. src += 3;
  325. des += 5;
  326. }
  327. a = src[0];
  328. b = src[1];
  329. des [0] = (UINT8) (a);
  330. des [1] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
  331. c = src[2] ;
  332. des [2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
  333. des [3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
  334. des [4] = (UINT8) (c);
  335. }
  336. /****************************************************************************
  337. *
  338. * ROUTINE : VerticalBand_3_5_Scale_C
  339. *
  340. * INPUTS : unsigned char *dest : Pointer to destination data.
  341. * unsigned int destPitch : Stride of destination data.
  342. * unsigned int destWidth : Width of destination data.
  343. *
  344. * OUTPUTS : None.
  345. *
  346. * RETURNS : void
  347. *
  348. * FUNCTION : Scales vertical band of pixels by scale 3 to 5. The
  349. * height of the band scaled is 3-pixels.
  350. *
  351. * SPECIAL NOTES : The routine uses the first line of the band below
  352. * the current band.
  353. *
  354. ****************************************************************************/
  355. void VerticalBand_3_5_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  356. {
  357. unsigned int i;
  358. unsigned int a, b, c;
  359. unsigned char *des = dest;
  360. for ( i=0; i<destWidth; i++ )
  361. {
  362. a = des [0];
  363. b = des [destPitch];
  364. des [destPitch] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
  365. c = des[destPitch*2];
  366. des [destPitch*2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
  367. des [destPitch*3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
  368. // First line in next band...
  369. a = des [destPitch * 5];
  370. des [destPitch * 4] = (UINT8) (( c * 154 + a * 102 + 128 ) >> 8);
  371. des++;
  372. }
  373. }
  374. /****************************************************************************
  375. *
  376. * ROUTINE : LastVerticalBand_3_5_Scale_C
  377. *
  378. * INPUTS : unsigned char *dest : Pointer to destination data.
  379. * unsigned int destPitch : Stride of destination data.
  380. * unsigned int destWidth : Width of destination data.
  381. *
  382. * OUTPUTS : None.
  383. *
  384. * RETURNS : void
  385. *
  386. * FUNCTION : Scales last vertical band of pixels by scale 3 to 5. The
  387. * height of the band scaled is 3-pixels.
  388. *
  389. * SPECIAL NOTES : The routine does not have available the first line of
  390. * the band below the current band, since this is the
  391. * last band.
  392. *
  393. ****************************************************************************/
  394. void LastVerticalBand_3_5_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  395. {
  396. unsigned int i;
  397. unsigned int a, b, c;
  398. unsigned char *des = dest;
  399. for ( i=0; i<destWidth; ++i )
  400. {
  401. a = des [0];
  402. b = des [destPitch];
  403. des [ destPitch ] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
  404. c = des[destPitch*2];
  405. des [destPitch*2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
  406. des [destPitch*3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
  407. // No other line for interplation of this line, so ..
  408. des [ destPitch * 4 ] = (UINT8) (c) ;
  409. des++;
  410. }
  411. }
  412. /****************************************************************************
  413. *
  414. * ROUTINE : Scale _3_5_2D
  415. *
  416. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  417. * const unsigned char *source : Pointer to source image.
  418. * unsigned int sourcePitch : Stride of source image.
  419. * unsigned int sourceWidth : Width of source image.
  420. * unsigned int sourceHeight : Height of source image (NOT USED).
  421. * unsigned char *dest : Pointer to destination image.
  422. * unsigned int destPitch : Stride of destination image.
  423. * unsigned int destWidth : Width of destination image.
  424. * unsigned int destHeight : Height of destination image.
  425. *
  426. * OUTPUTS : None.
  427. *
  428. * RETURNS : void
  429. *
  430. * FUNCTION : Two-dimensional 3 to 5 scaling up of an image.
  431. *
  432. * SPECIAL NOTES : None.
  433. *
  434. ****************************************************************************/
  435. void Scale_3_5_2D
  436. (
  437. POSTPROC_INSTANCE *ppi,
  438. const unsigned char *source,
  439. unsigned int sourcePitch,
  440. unsigned int sourceWidth,
  441. unsigned int sourceHeight,
  442. unsigned char *dest,
  443. unsigned int destPitch,
  444. unsigned int destWidth,
  445. unsigned int destHeight
  446. )
  447. {
  448. // define the constants for a 3->5 scale up
  449. const unsigned int srcBandHeight = 3;
  450. const unsigned int destBandHeight = 5;
  451. unsigned int i, k;
  452. (void) ppi;
  453. (void) sourceHeight;
  454. HorizontalLine_3_5_Scale ( source, sourceWidth, dest, destWidth );
  455. // Except last band
  456. for ( k=0; k<destHeight/destBandHeight-1; k++ )
  457. {
  458. // scale one band horizontally
  459. for ( i=1; i<srcBandHeight; i++ )
  460. {
  461. HorizontalLine_3_5_Scale ( source+i*sourcePitch,
  462. sourceWidth,
  463. dest+i*destPitch,
  464. destWidth );
  465. }
  466. // First line of next band
  467. HorizontalLine_3_5_Scale ( source+srcBandHeight*sourcePitch,
  468. sourceWidth,
  469. dest+destBandHeight*destPitch,
  470. destWidth );
  471. // Vertical scaling is in place
  472. VerticalBand_3_5_Scale ( dest, destPitch, destWidth );
  473. // move to the next band
  474. source += srcBandHeight * sourcePitch;
  475. dest += destBandHeight * destPitch;
  476. }
  477. // scale one band horizontally
  478. for ( i=1; i<srcBandHeight; i++ )
  479. {
  480. HorizontalLine_3_5_Scale ( source+i*sourcePitch,
  481. sourceWidth,
  482. dest+i*destPitch,
  483. destWidth );
  484. }
  485. // Vertical scaling is in place
  486. LastVerticalBand_3_5_Scale ( dest, destPitch, destWidth );
  487. }
  488. /****************************************************************************
  489. *
  490. * ROUTINE : HorizontalLine_1_2_Scale_C
  491. *
  492. * INPUTS : const unsigned char *source : Pointer to source data.
  493. * unsigned int sourceWidth : Stride of source.
  494. * unsigned char *dest : Pointer to destination data.
  495. * unsigned int destWidth : Stride of destination (NOT USED).
  496. *
  497. * OUTPUTS : None.
  498. *
  499. * RETURNS : void
  500. *
  501. * FUNCTION : Copies horizontal line of pixels from source to
  502. * destination scaling up by 1 to 2.
  503. *
  504. * SPECIAL NOTES : None.
  505. *
  506. ****************************************************************************/
  507. void HorizontalLine_1_2_Scale_C
  508. (
  509. const unsigned char *source,
  510. unsigned int sourceWidth,
  511. unsigned char *dest,
  512. unsigned int destWidth
  513. )
  514. {
  515. unsigned int i;
  516. unsigned int a, b;
  517. unsigned char *des = dest;
  518. const unsigned char *src = source;
  519. (void) destWidth;
  520. for ( i=0; i<sourceWidth-1; i+=1 )
  521. {
  522. a = src[0];
  523. b = src[1];
  524. des [0] = (UINT8) (a);
  525. des [1] = (UINT8) (( a + b + 1 ) >> 1);
  526. src += 1;
  527. des += 2;
  528. }
  529. a = src[0];
  530. des [0] = (UINT8) (a);
  531. des [1] = (UINT8) (a);
  532. }
  533. /****************************************************************************
  534. *
  535. * ROUTINE : VerticalBand_1_2_Scale_C
  536. *
  537. * INPUTS : unsigned char *dest : Pointer to destination data.
  538. * unsigned int destPitch : Stride of destination data.
  539. * unsigned int destWidth : Width of destination data.
  540. *
  541. * OUTPUTS : None.
  542. *
  543. * RETURNS : void
  544. *
  545. * FUNCTION : Scales vertical band of pixels by scale 1 to 2. The
  546. * height of the band scaled is 1-pixel.
  547. *
  548. * SPECIAL NOTES : The routine uses the first line of the band below
  549. * the current band.
  550. *
  551. ****************************************************************************/
  552. void VerticalBand_1_2_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  553. {
  554. unsigned int i;
  555. unsigned int a, b;
  556. unsigned char *des = dest;
  557. for ( i=0; i<destWidth; i++ )
  558. {
  559. a = des [0];
  560. b = des [destPitch * 2];
  561. des[destPitch] = (UINT8) ((a + b + 1 )>>1);
  562. des++;
  563. }
  564. }
  565. /****************************************************************************
  566. *
  567. * ROUTINE : LastVerticalBand_1_2_Scale_C
  568. *
  569. * INPUTS : unsigned char *dest : Pointer to destination data.
  570. * unsigned int destPitch : Stride of destination data.
  571. * unsigned int destWidth : Width of destination data.
  572. *
  573. * OUTPUTS : None.
  574. *
  575. * RETURNS : void
  576. *
  577. * FUNCTION : Scales last vertical band of pixels by scale 1 to 2. The
  578. * height of the band scaled is 1-pixel.
  579. *
  580. * SPECIAL NOTES : The routine does not have available the first line of
  581. * the band below the current band, since this is the
  582. * last band.
  583. *
  584. ****************************************************************************/
  585. void LastVerticalBand_1_2_Scale_C ( unsigned char *dest, unsigned int destPitch, unsigned int destWidth )
  586. {
  587. unsigned int i;
  588. unsigned char *des = dest;
  589. for ( i=0; i<destWidth; ++i )
  590. {
  591. des[destPitch] = des[0];
  592. des++;
  593. }
  594. }
  595. /****************************************************************************
  596. *
  597. * ROUTINE : Scale1D_c
  598. *
  599. * INPUTS : const unsigned char *source : Pointer to data to be scaled.
  600. * int sourceStep : Number of pixels to step on in source.
  601. * unsigned int sourceScale : Scale for source.
  602. * unsigned int sourceLength : Length of source (UNUSED).
  603. * unsigned char *dest : Pointer to output data array.
  604. * int destStep : Number of pixels to step on in destination.
  605. * unsigned int destScale : Scale for destination.
  606. * unsigned int destLength : Length of destination.
  607. *
  608. * OUTPUTS : None.
  609. *
  610. * RETURNS : void
  611. *
  612. * FUNCTION : Performs linear interpolation in one dimension.
  613. *
  614. * SPECIAL NOTES : None.
  615. *
  616. ****************************************************************************/
  617. void Scale1D_c
  618. (
  619. const unsigned char *source,
  620. int sourceStep,
  621. unsigned int sourceScale,
  622. unsigned int sourceLength,
  623. unsigned char *dest,
  624. int destStep,
  625. unsigned int destScale,
  626. unsigned int destLength
  627. )
  628. {
  629. unsigned int i;
  630. unsigned int roundValue = destScale / 2;
  631. unsigned int leftModifier = destScale;
  632. unsigned int rightModifier = 0;
  633. unsigned char leftPixel = *source;
  634. unsigned char rightPixel = *( source + sourceStep );
  635. (void) sourceLength;
  636. // These asserts are needed if there are boundary issues...
  637. //assert ( destScale > sourceScale );
  638. //assert ( (sourceLength-1) * destScale >= (destLength-1) * sourceScale );
  639. for ( i=0; i<destLength*destStep; i+=destStep )
  640. {
  641. dest[i] = (INT8)((leftModifier*leftPixel + rightModifier*rightPixel + roundValue) / destScale);
  642. rightModifier += sourceScale;
  643. while ( rightModifier > destScale )
  644. {
  645. rightModifier -= destScale;
  646. source += sourceStep;
  647. leftPixel = *source;
  648. rightPixel = *( source + sourceStep );
  649. }
  650. leftModifier = destScale - rightModifier;
  651. }
  652. }
  653. /****************************************************************************
  654. *
  655. * ROUTINE : Scale1D_2t1_i
  656. *
  657. * INPUTS : const unsigned char *source : Pointer to data to be scaled.
  658. * int sourceStep : Number of pixels to step on in source.
  659. * unsigned int sourceScale : Scale for source (UNUSED).
  660. * unsigned int sourceLength : Length of source (UNUSED).
  661. * unsigned char *dest : Pointer to output data array.
  662. * int destStep : Number of pixels to step on in destination.
  663. * unsigned int destScale : Scale for destination (UNUSED).
  664. * unsigned int destLength : Length of destination.
  665. *
  666. * OUTPUTS : None.
  667. *
  668. * RETURNS : void
  669. *
  670. * FUNCTION : Performs 2-to-1 interpolated scaling.
  671. *
  672. * SPECIAL NOTES : None.
  673. *
  674. ****************************************************************************/
  675. void Scale1D_2t1_i
  676. (
  677. const unsigned char *source,
  678. int sourceStep,
  679. unsigned int sourceScale,
  680. unsigned int sourceLength,
  681. unsigned char *dest,
  682. int destStep,
  683. unsigned int destScale,
  684. unsigned int destLength
  685. )
  686. {
  687. unsigned int i, j;
  688. unsigned int temp;
  689. (void) sourceLength;
  690. (void) sourceScale;
  691. (void) destScale;
  692. sourceStep *= 2;
  693. dest[0] = source[0];
  694. for ( i=destStep, j=sourceStep; i<destLength*destStep; i+=destStep, j+=sourceStep )
  695. {
  696. temp = 8;
  697. temp += 3 * source[j-sourceStep];
  698. temp += 10 * source[j];
  699. temp += 3 * source[j+sourceStep];
  700. temp >>= 4;
  701. dest[i] = (INT8) (temp);
  702. }
  703. }
  704. /****************************************************************************
  705. *
  706. * ROUTINE : Scale1D_2t1_ps
  707. *
  708. * INPUTS : const unsigned char *source : Pointer to data to be scaled.
  709. * int sourceStep : Number of pixels to step on in source.
  710. * unsigned int sourceScale : Scale for source (UNUSED).
  711. * unsigned int sourceLength : Length of source (UNUSED).
  712. * unsigned char *dest : Pointer to output data array.
  713. * int destStep : Number of pixels to step on in destination.
  714. * unsigned int destScale : Scale for destination (UNUSED).
  715. * unsigned int destLength : Length of destination.
  716. *
  717. * OUTPUTS : None.
  718. *
  719. * RETURNS : void
  720. *
  721. * FUNCTION : Performs 2-to-1 point subsampled scaling.
  722. *
  723. * SPECIAL NOTES : None.
  724. *
  725. ****************************************************************************/
  726. void Scale1D_2t1_ps
  727. (
  728. const unsigned char *source,
  729. int sourceStep,
  730. unsigned int sourceScale,
  731. unsigned int sourceLength,
  732. unsigned char *dest,
  733. int destStep,
  734. unsigned int destScale,
  735. unsigned int destLength
  736. )
  737. {
  738. unsigned int i, j;
  739. (void) sourceLength;
  740. (void) sourceScale;
  741. (void) destScale;
  742. sourceStep *= 2;
  743. j = 0;
  744. for ( i=0; i<destLength*destStep; i+=destStep, j+=sourceStep )
  745. dest[i] = source[j];
  746. }
  747. /****************************************************************************
  748. *
  749. * ROUTINE : Scale2D
  750. *
  751. * INPUTS : const unsigned char *source : Pointer to data to be scaled.
  752. * int sourcePitch : Stride of source image.
  753. * unsigned int sourceWidth : Width of input image.
  754. * unsigned int sourceHeight : Height of input image.
  755. * unsigned char *dest : Pointer to output data array.
  756. * int destPitch : Stride of destination image.
  757. * unsigned int destWidth : Width of destination image.
  758. * unsigned int destHeight : Height of destination image.
  759. * unsigned char *tempArea : Pointer to temp work area.
  760. * unsigned char tempAreaHeight : Height of temp work area.
  761. * unsigned int hscale : Horizontal scale factor numerator.
  762. * unsigned int hratio : Horizontal scale factor denominator.
  763. * unsigned int vscale : Vertical scale factor numerator.
  764. * unsigned int vratio : Vertical scale factor denominator.
  765. * unsigned int interlaced : Interlace flag.
  766. *
  767. * OUTPUTS : None.
  768. *
  769. * RETURNS : void
  770. *
  771. * FUNCTION : Performs 2-tap linear interpolation in two dimensions.
  772. *
  773. * SPECIAL NOTES : Expansion is performed one band at a time to help with
  774. * caching.
  775. *
  776. ****************************************************************************/
  777. void Scale2D
  778. (
  779. const unsigned char *source,
  780. int sourcePitch,
  781. unsigned int sourceWidth,
  782. unsigned int sourceHeight,
  783. unsigned char *dest,
  784. int destPitch,
  785. unsigned int destWidth,
  786. unsigned int destHeight,
  787. unsigned char *tempArea,
  788. unsigned char tempAreaHeight,
  789. unsigned int hscale,
  790. unsigned int hratio,
  791. unsigned int vscale,
  792. unsigned int vratio,
  793. unsigned int interlaced
  794. )
  795. {
  796. unsigned int i, j, k;
  797. unsigned int bands;
  798. unsigned int destBandHeight;
  799. unsigned int sourceBandHeight;
  800. typedef void (*Scale1D)( const unsigned char *source,int sourceStep,unsigned int sourceScale,unsigned int sourceLength,
  801. unsigned char *dest,int destStep,unsigned int destScale,unsigned int destLength);
  802. Scale1D Scale1Dv = Scale1D_c;
  803. Scale1D Scale1Dh = Scale1D_c;
  804. if ( hscale==2 && hratio==1 )
  805. Scale1Dh = Scale1D_2t1_ps;
  806. if ( vscale==2 && vratio==1 )
  807. {
  808. if ( interlaced )
  809. Scale1Dv = Scale1D_2t1_ps;
  810. else
  811. Scale1Dv = Scale1D_2t1_i;
  812. }
  813. if ( sourceHeight == destHeight )
  814. {
  815. // for each band of the image
  816. for ( k=0; k<destHeight; k++ )
  817. {
  818. Scale1Dh ( source, 1, hscale, sourceWidth+1, dest, 1, hratio, destWidth );
  819. source += sourcePitch;
  820. dest += destPitch;
  821. }
  822. return;
  823. }
  824. if ( destHeight > sourceHeight )
  825. {
  826. destBandHeight = tempAreaHeight - 1;
  827. sourceBandHeight = destBandHeight * sourceHeight / destHeight;
  828. }
  829. else
  830. {
  831. sourceBandHeight = tempAreaHeight - 1;
  832. destBandHeight = sourceBandHeight * vratio / vscale;
  833. }
  834. // first row needs to be done so that we can stay one row ahead for vertical zoom
  835. Scale1Dh ( source, 1, hscale, sourceWidth+1, tempArea, 1, hratio, destWidth );
  836. // for each band of the image
  837. bands = (destHeight + destBandHeight - 1)/ destBandHeight;
  838. for ( k=0; k<bands; k++ )
  839. {
  840. // scale one band horizontally
  841. for ( i=1; i<sourceBandHeight+1; i++ )
  842. {
  843. if ( k*sourceBandHeight+i < sourceHeight )
  844. {
  845. Scale1Dh ( source+i*sourcePitch, 1, hscale, sourceWidth+1,
  846. tempArea+i*destPitch, 1, hratio, destWidth );
  847. }
  848. else // Duplicate the last row
  849. {
  850. // copy tempArea row 0 over from last row in the past
  851. memcpy ( tempArea+i*destPitch, tempArea+(i-1)*destPitch, destPitch );
  852. }
  853. }
  854. // scale one band vertically
  855. for ( j=0; j<destWidth; j++ )
  856. {
  857. Scale1Dv ( &tempArea[j], destPitch, vscale, sourceBandHeight+1,
  858. &dest[j], destPitch, vratio, destBandHeight );
  859. }
  860. // copy tempArea row 0 over from last row in the past
  861. memcpy ( tempArea, tempArea+sourceBandHeight*destPitch, destPitch );
  862. // move to the next band
  863. source += sourceBandHeight * sourcePitch;
  864. dest += destBandHeight * destPitch;
  865. }
  866. }
  867. /****************************************************************************
  868. *
  869. * ROUTINE : ScaleFrame
  870. *
  871. * INPUTS : YUV_BUFFER_CONFIG *src : Pointer to frame to be scaled.
  872. * YUV_BUFFER_CONFIG *dst : Pointer to buffer to hold scaled frame.
  873. * unsigned char *tempArea : Pointer to temp work area.
  874. * unsigned char tempAreaHeight : Height of temp work area.
  875. * unsigned int hscale : Horizontal scale factor numerator.
  876. * unsigned int hratio : Horizontal scale factor denominator.
  877. * unsigned int vscale : Vertical scale factor numerator.
  878. * unsigned int vratio : Vertical scale factor denominator.
  879. * unsigned int interlaced : Interlace flag.
  880. *
  881. * OUTPUTS : None.
  882. *
  883. * RETURNS : void
  884. *
  885. * FUNCTION : Performs 2-tap linear interpolation in two dimensions.
  886. *
  887. * SPECIAL NOTES : Expansion is performed one band at a time to help with
  888. * caching.
  889. *
  890. ****************************************************************************/
  891. void ScaleFrame
  892. (
  893. YUV_BUFFER_CONFIG *src,
  894. YUV_BUFFER_CONFIG *dst,
  895. unsigned char *tempArea,
  896. unsigned char tempHeight,
  897. unsigned int hscale,
  898. unsigned int hratio,
  899. unsigned int vscale,
  900. unsigned int vratio,
  901. unsigned int interlaced
  902. )
  903. {
  904. int i;
  905. int dw = (hscale - 1 + src->YWidth * hratio) / hscale;
  906. int dh = (vscale - 1 + src->YHeight * vratio) / vscale;
  907. // call our internal scaling routines!!
  908. Scale2D ( (unsigned char *) src->YBuffer, src->YStride, src->YWidth, src->YHeight,
  909. (unsigned char *) dst->YBuffer, dst->YStride, dw, dh,
  910. tempArea, tempHeight, hscale, hratio, vscale, vratio, interlaced );
  911. if ( dw < (int)dst->YWidth )
  912. for ( i=0; i<dh; i++ )
  913. memset ( dst->YBuffer+i*dst->YStride+dw-1, dst->YBuffer[i*dst->YStride+dw-2], dst->YWidth-dw+1 );
  914. if ( dh < (int)dst->YHeight )
  915. for ( i=dh-1; i<(int)dst->YHeight; i++ )
  916. memcpy(dst->YBuffer + i*dst->YStride, dst->YBuffer + (dh-2) * dst->YStride, dst->YWidth+1);
  917. Scale2D ( (unsigned char *) src->UBuffer,src->UVStride, src->UVWidth, src->UVHeight,
  918. (unsigned char *) dst->UBuffer,dst->UVStride, dw/2, dh/2,
  919. tempArea, tempHeight, hscale, hratio, vscale, vratio, interlaced );
  920. if ( dw/2 < (int)dst->UVWidth )
  921. for(i=0;i<dst->UVHeight;i++)
  922. memset(dst->UBuffer + i * dst->UVStride + dw/2 - 1, dst->UBuffer[i*dst->UVStride+dw/2-2],dst->UVWidth-dw/2 + 1);
  923. if ( dh/2 < (int)dst->UVHeight )
  924. for ( i=dh/2-1; i<(int)dst->YHeight/2; i++ )
  925. memcpy ( dst->UBuffer+i*dst->UVStride, dst->UBuffer+(dh/2-2)*dst->UVStride, dst->UVWidth );
  926. Scale2D ( (unsigned char *) src->VBuffer,src->UVStride, src->UVWidth, src->UVHeight,
  927. (unsigned char *) dst->VBuffer,dst->UVStride, dw/2, dh/2,
  928. tempArea, tempHeight, hscale, hratio, vscale, vratio, interlaced );
  929. if ( dw/2 < (int)dst->UVWidth )
  930. for ( i=0; i<dst->UVHeight; i++ )
  931. memset ( dst->VBuffer+i*dst->UVStride+dw/2-1, dst->VBuffer[i*dst->UVStride+dw/2-2], dst->UVWidth-dw/2+1 );
  932. if ( dh/2 < (int) dst->UVHeight )
  933. for ( i=dh/2-1; i<(int)dst->YHeight/2; i++ )
  934. memcpy ( dst->VBuffer+i*dst->UVStride, dst->VBuffer+(dh/2-2)*dst->UVStride, dst->UVWidth );
  935. }
  936. /****************************************************************************
  937. *
  938. * ROUTINE : Fast_4_5_Scale
  939. *
  940. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  941. * UINT8 *FrameBuffer : Pointer to source image.
  942. * YUV_BUFFER_CONFIG *YuvConfig : Pointer to destination image.
  943. *
  944. * OUTPUTS : None.
  945. *
  946. * RETURNS : void
  947. *
  948. * FUNCTION : Scales up image by factor of 5/4, creating 5 output
  949. * samples for every 4 input samples horizontally &
  950. * vertically.
  951. *
  952. * SPECIAL NOTES : None.
  953. *
  954. ****************************************************************************/
  955. void Fast_4_5_Scale ( POSTPROC_INSTANCE *ppi, UINT8 *FrameBuffer, YUV_BUFFER_CONFIG *YuvConfig )
  956. {
  957. // check that width and height are valid please..!
  958. int h = ppi->Configuration.VideoFrameHeight;
  959. int w = ppi->Configuration.VideoFrameWidth;
  960. int nh = YuvConfig->YHeight;
  961. int nw = YuvConfig->YWidth;
  962. Scale_4_5_2D ( ppi, &FrameBuffer[ppi->ReconYDataOffset], w+32, w, h,
  963. (UINT8 *)YuvConfig->YBuffer, nw, nw, nh );
  964. w >>= 1;
  965. h >>= 1;
  966. nw >>= 1;
  967. nh >>= 1;
  968. Scale_4_5_2D ( ppi, &FrameBuffer[ppi->ReconUDataOffset], w+16, w, h,
  969. (UINT8 *)YuvConfig->UBuffer, nw, nw, nh );
  970. Scale_4_5_2D ( ppi, &FrameBuffer[ppi->ReconVDataOffset], w+16, w, h,
  971. (UINT8 *)YuvConfig->VBuffer, nw, nw, nh );
  972. }
  973. /****************************************************************************
  974. *
  975. * ROUTINE : Fast_3_5_Scale
  976. *
  977. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  978. * UINT8 *FrameBuffer : Pointer to source image.
  979. * YUV_BUFFER_CONFIG *YuvConfig : Pointer to destination image.
  980. *
  981. * OUTPUTS : None.
  982. *
  983. * RETURNS : void
  984. *
  985. * FUNCTION : Scales up image by factor of 5/3, creating 5 output
  986. * samples for every 3 input samples horizontally &
  987. * vertically.
  988. *
  989. * SPECIAL NOTES : None.
  990. *
  991. ****************************************************************************/
  992. void Fast_3_5_Scale ( POSTPROC_INSTANCE *ppi, UINT8 *FrameBuffer, YUV_BUFFER_CONFIG *YuvConfig )
  993. {
  994. // check that width and height are valid please..!
  995. int h = ppi->Configuration.VideoFrameHeight;
  996. int w = ppi->Configuration.VideoFrameWidth;
  997. int nh = YuvConfig->YHeight;
  998. int nw = YuvConfig->YWidth;
  999. Scale_3_5_2D ( ppi, &FrameBuffer[ppi->ReconYDataOffset], w+32, w, h,
  1000. (UINT8 *)YuvConfig->YBuffer, nw, nw, nh );
  1001. w >>= 1;
  1002. h >>= 1;
  1003. nw >>= 1;
  1004. nh >>= 1;
  1005. Scale_3_5_2D ( ppi, &FrameBuffer[ppi->ReconUDataOffset], w+16, w, h,
  1006. (UINT8 *)YuvConfig->UBuffer, nw, nw, nh );
  1007. Scale_3_5_2D ( ppi, &FrameBuffer[ppi->ReconVDataOffset], w+16, w, h,
  1008. (UINT8 *)YuvConfig->VBuffer, nw, nw, nh );
  1009. }
  1010. /****************************************************************************
  1011. *
  1012. * ROUTINE : AnyRatio_2D_Scale
  1013. *
  1014. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  1015. * const unsigned char *source : Pointer to source image.
  1016. * unsigned int sourcePitch : Stride of source image.
  1017. * unsigned int sourceWidth : Width of source image.
  1018. * unsigned int sourceHeight : Height of source image (NOT USED).
  1019. * unsigned char *dest : Pointer to destination image.
  1020. * unsigned int destPitch : Stride of destination image.
  1021. * unsigned int destWidth : Width of destination image.
  1022. * unsigned int destHeight : Height of destination image.
  1023. *
  1024. * OUTPUTS : None.
  1025. *
  1026. * RETURNS : int: 1 if image scaled, 0 if image could not be scaled.
  1027. *
  1028. * FUNCTION : Scale the image with changing apect ratio.
  1029. *
  1030. * SPECIAL NOTES : This scaling is a bi-linear scaling. Need to re-work the
  1031. * whole function for new scaling algorithm.
  1032. *
  1033. ****************************************************************************/
  1034. int AnyRatio_2D_Scale
  1035. (
  1036. POSTPROC_INSTANCE *ppi,
  1037. const unsigned char *source,
  1038. unsigned int sourcePitch,
  1039. unsigned int sourceWidth,
  1040. unsigned int sourceHeight,
  1041. unsigned char *dest,
  1042. unsigned int destPitch,
  1043. unsigned int destWidth,
  1044. unsigned int destHeight
  1045. )
  1046. {
  1047. unsigned int i, k, max_k;
  1048. unsigned int srcBandHeight = 0;
  1049. unsigned int destBandHeight = 0;
  1050. // suggested scale factors
  1051. int hs = ppi->Configuration.HScale;
  1052. int hr = ppi->Configuration.HRatio;
  1053. int vs = ppi->Configuration.VScale;
  1054. int vr = ppi->Configuration.VRatio;
  1055. // assume the ratios are scalable instead of should be centered
  1056. int RatioScalable = 1;
  1057. void (*HorizLineScale) ( const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
  1058. void (*VertBandScale) ( unsigned char *, unsigned int, unsigned int) = NULL;
  1059. void (*LastVertBandScale) ( unsigned char *, unsigned int, unsigned int) = NULL;
  1060. (void) ppi;
  1061. // find out the ratio for each direction
  1062. switch ( hr*10/hs )
  1063. {
  1064. case 8:
  1065. // 4-5 Scale in Width direction
  1066. HorizLineScale = HorizontalLine_4_5_Scale;
  1067. break;
  1068. case 6:
  1069. // 3-5 Scale in Width direction
  1070. HorizLineScale = HorizontalLine_3_5_Scale;
  1071. break;
  1072. case 5:
  1073. // 1-2 Scale in Width direction
  1074. HorizLineScale = HorizontalLine_1_2_Scale;
  1075. break;
  1076. case 10:
  1077. // no scale in Width direction
  1078. HorizLineScale = HorizontalLine_Copy;
  1079. break;
  1080. default:
  1081. // The ratio is not acceptable now
  1082. // throw("The ratio is not acceptable for now!");
  1083. RatioScalable = 0;
  1084. break;
  1085. }
  1086. switch ( vr*10/vs )
  1087. {
  1088. case 8:
  1089. // 4-5 Scale in vertical direction
  1090. VertBandScale = VerticalBand_4_5_Scale;
  1091. LastVertBandScale = LastVerticalBand_4_5_Scale;
  1092. srcBandHeight = 4;
  1093. destBandHeight = 5;
  1094. break;
  1095. case 6:
  1096. // 3-5 Scale in vertical direction
  1097. VertBandScale = VerticalBand_3_5_Scale;
  1098. LastVertBandScale = LastVerticalBand_3_5_Scale;
  1099. srcBandHeight = 3;
  1100. destBandHeight = 5;
  1101. break;
  1102. case 5:
  1103. // 1-2 Scale in vertical direction
  1104. VertBandScale = VerticalBand_1_2_Scale;
  1105. LastVertBandScale = LastVerticalBand_1_2_Scale;
  1106. srcBandHeight = 1;
  1107. destBandHeight = 2;
  1108. break;
  1109. case 10:
  1110. // no scale in Width direction
  1111. VertBandScale = NullScale;
  1112. LastVertBandScale = NullScale;
  1113. srcBandHeight = 4;
  1114. destBandHeight = 4;
  1115. break;
  1116. default:
  1117. // The ratio is not acceptable now
  1118. // throw("The ratio is not acceptable for now!");
  1119. RatioScalable = 0;
  1120. break;
  1121. }
  1122. if ( RatioScalable == 0 )
  1123. return RatioScalable;
  1124. HorizLineScale ( source, sourceWidth, dest, destWidth );
  1125. // except last band
  1126. max_k = (destHeight+destBandHeight-1)/destBandHeight;
  1127. if (max_k)
  1128. {
  1129. for ( k=0; k<max_k-1; k++ )
  1130. {
  1131. // scale one band horizontally
  1132. for ( i=1; i<srcBandHeight; i++ )
  1133. {
  1134. HorizLineScale ( source+i*sourcePitch,
  1135. sourceWidth,
  1136. dest+i*destPitch,
  1137. destWidth );
  1138. }
  1139. // first line of next band
  1140. HorizLineScale ( source+srcBandHeight*sourcePitch,
  1141. sourceWidth,
  1142. dest+destBandHeight*destPitch,
  1143. destWidth );
  1144. // Vertical scaling is in place
  1145. VertBandScale ( dest, destPitch, destWidth );
  1146. // Next band...
  1147. source += srcBandHeight * sourcePitch;
  1148. dest += destBandHeight * destPitch;
  1149. }
  1150. // scale one band horizontally
  1151. for ( i=1; i<srcBandHeight; i++ )
  1152. {
  1153. HorizLineScale ( source+i*sourcePitch,
  1154. sourceWidth,
  1155. dest+i*destPitch,
  1156. destWidth );
  1157. }
  1158. // Vertical scaling is in place
  1159. LastVertBandScale ( dest, destPitch, destWidth );
  1160. }
  1161. return RatioScalable;
  1162. }
  1163. /****************************************************************************
  1164. *
  1165. * ROUTINE : AnyRatioFrameScale
  1166. *
  1167. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance (NOT USED).
  1168. * UINT8 *FrameBuffer : Pointer to source image.
  1169. * YUV_BUFFER_CONFIG *YuvConfig : Pointer to destination image.
  1170. * INT32 YOffset : Offset from start of buffer to Y samples.
  1171. * INT32 UVOffset : Offset from start of buffer to UV samples.
  1172. *
  1173. * OUTPUTS : None.
  1174. *
  1175. * RETURNS : int: 1 if image scaled, 0 if image could not be scaled.
  1176. *
  1177. * FUNCTION : Scale the image with changing apect ratio.
  1178. *
  1179. * SPECIAL NOTES : None.
  1180. *
  1181. ****************************************************************************/
  1182. int AnyRatioFrameScale
  1183. (
  1184. POSTPROC_INSTANCE *ppi,
  1185. UINT8 *FrameBuffer,
  1186. YUV_BUFFER_CONFIG *YuvConfig,
  1187. INT32 YOffset,
  1188. INT32 UVOffset
  1189. )
  1190. {
  1191. int i;
  1192. int ew;
  1193. int eh;
  1194. // suggested scale factors
  1195. int hs = ppi->Configuration.HScale;
  1196. int hr = ppi->Configuration.HRatio;
  1197. int vs = ppi->Configuration.VScale;
  1198. int vr = ppi->Configuration.VRatio;
  1199. int RatioScalable = 1;
  1200. int sw = (ppi->Configuration.ExpandedFrameWidth * hr + hs - 1)/hs;
  1201. int sh = (ppi->Configuration.ExpandedFrameHeight * vr + vs - 1)/vs;
  1202. int dw = ppi->Configuration.ExpandedFrameWidth;
  1203. int dh = ppi->Configuration.ExpandedFrameHeight;
  1204. if ( hr == 3 )
  1205. ew = (sw+2)/3 * 3 * hs / hr;
  1206. else
  1207. ew = (sw+7)/8 * 8 * hs / hr;
  1208. if ( vr == 3 )
  1209. eh = (sh+2)/3 * 3 * vs / vr;
  1210. else
  1211. eh = (sh+7)/8 * 8 * vs / vr;
  1212. RatioScalable = AnyRatio_2D_Scale ( ppi, &FrameBuffer[ppi->ReconYDataOffset],
  1213. ppi->Configuration.VideoFrameWidth +ppi->MVBorder*2, sw, sh,
  1214. (UINT8 *) YuvConfig->YBuffer + YOffset, YuvConfig->YStride, dw, dh);
  1215. for ( i=0; i<eh; i++ )
  1216. memset ( YuvConfig->YBuffer+YOffset+i*YuvConfig->YStride+dw, 0, ew-dw );
  1217. for ( i=dh; i<eh; i++ )
  1218. memset ( YuvConfig->YBuffer+YOffset+i*YuvConfig->YStride, 0, ew );
  1219. if ( RatioScalable==0 )
  1220. return RatioScalable;
  1221. sw = (sw+1)>>1;
  1222. sh = (sh+1)>>1;
  1223. dw = (dw+1)>>1;
  1224. dh = (dh+1)>>1;
  1225. AnyRatio_2D_Scale ( ppi, &FrameBuffer[ppi->ReconUDataOffset], ppi->Configuration.VideoFrameWidth/2+ppi->MVBorder, sw,sh,
  1226. (UINT8 *)YuvConfig->UBuffer+UVOffset, YuvConfig->UVStride, dw, dh );
  1227. AnyRatio_2D_Scale ( ppi, &FrameBuffer[ppi->ReconVDataOffset], ppi->Configuration.VideoFrameWidth/2+ppi->MVBorder, sw, sh,
  1228. (UINT8 *)YuvConfig->VBuffer+UVOffset, YuvConfig->UVStride, dw, dh );
  1229. return RatioScalable;
  1230. }
  1231. /****************************************************************************
  1232. *
  1233. * ROUTINE : CenterImage
  1234. *
  1235. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance.
  1236. * UINT8 *FrameBuffer : Pointer to source image.
  1237. * YUV_BUFFER_CONFIG *YuvConfig : Pointer to destination image.
  1238. *
  1239. * OUTPUTS : None.
  1240. *
  1241. * RETURNS : void
  1242. *
  1243. * FUNCTION : Centers the image without scaling in the output buffer.
  1244. *
  1245. * SPECIAL NOTES : None.
  1246. *
  1247. ****************************************************************************/
  1248. void CCONV CenterImage ( POSTPROC_INSTANCE *ppi, UINT8 *FrameBuffer, YUV_BUFFER_CONFIG *YuvConfig )
  1249. {
  1250. UINT32 i;
  1251. INT32 RowOffset, ColOffset;
  1252. UINT8 *SrcDataPointer;
  1253. UINT8 *DstDataPointer;
  1254. // center values
  1255. RowOffset = (YuvConfig->YHeight - ppi->Configuration.VideoFrameHeight)/2;
  1256. ColOffset = (YuvConfig->YWidth - ppi->Configuration.VideoFrameWidth)/2;
  1257. // Y's
  1258. SrcDataPointer = &FrameBuffer[ppi->ReconYDataOffset];
  1259. DstDataPointer = (UINT8 *)YuvConfig->YBuffer+RowOffset*YuvConfig->YWidth+ColOffset;
  1260. for ( i=0; i<ppi->Configuration.VideoFrameHeight; i++ )
  1261. {
  1262. memcpy ( DstDataPointer, SrcDataPointer, ppi->Configuration.VideoFrameWidth );
  1263. DstDataPointer += YuvConfig->YWidth;
  1264. SrcDataPointer += ppi->YStride;
  1265. }
  1266. // U's
  1267. SrcDataPointer = &FrameBuffer[ppi->ReconUDataOffset];
  1268. DstDataPointer = (UINT8 *)YuvConfig->UBuffer+RowOffset/2*YuvConfig->UVWidth+ColOffset/2;
  1269. for ( i=0; i<ppi->Configuration.VideoFrameHeight/2; i++ )
  1270. {
  1271. memcpy ( DstDataPointer, SrcDataPointer, ppi->Configuration.VideoFrameWidth/2 );
  1272. DstDataPointer += YuvConfig->UVWidth;
  1273. SrcDataPointer += ppi->UVStride;
  1274. }
  1275. // V's
  1276. SrcDataPointer = &FrameBuffer[ppi->ReconVDataOffset];
  1277. DstDataPointer = (UINT8 *)YuvConfig->VBuffer+RowOffset/2*YuvConfig->UVWidth+ColOffset/2;
  1278. for ( i=0; i<ppi->Configuration.VideoFrameHeight/2; i++ )
  1279. {
  1280. memcpy ( DstDataPointer, SrcDataPointer, ppi->Configuration.VideoFrameWidth/2 );
  1281. DstDataPointer += YuvConfig->UVWidth;
  1282. SrcDataPointer += ppi->UVStride;
  1283. }
  1284. }
  1285. /****************************************************************************
  1286. *
  1287. * ROUTINE : ScaleOrCenter
  1288. *
  1289. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processor instance.
  1290. * UINT8 *FrameBuffer : Pointer to source image.
  1291. * YUV_BUFFER_CONFIG *YuvConfig : Pointer to destination image.
  1292. *
  1293. * OUTPUTS : None.
  1294. *
  1295. * RETURNS : void
  1296. *
  1297. * FUNCTION : Centers the image without scaling in the output buffer.
  1298. *
  1299. * FUNCTION : Decides to scale or center image in scale buffer for blit
  1300. *
  1301. * SPECIAL NOTES : None.
  1302. *
  1303. ****************************************************************************/
  1304. void CCONV ScaleOrCenter
  1305. (
  1306. POSTPROC_INSTANCE *ppi,
  1307. UINT8 *FrameBuffer,
  1308. YUV_BUFFER_CONFIG *YuvConfig
  1309. )
  1310. {
  1311. if ( ppi->PostProcessingLevel )
  1312. UpdateUMVBorder ( ppi, FrameBuffer );
  1313. switch ( ppi->Configuration.ScalingMode )
  1314. {
  1315. case SCALE_TO_FIT:
  1316. case MAINTAIN_ASPECT_RATIO:
  1317. {
  1318. // center values
  1319. int row = (YuvConfig->YHeight - (int)ppi->Configuration.ExpandedFrameHeight ) / 2;
  1320. int col = (YuvConfig->YWidth - (int)ppi->Configuration.ExpandedFrameWidth ) / 2;
  1321. int YOffset = row * YuvConfig->YWidth + col;
  1322. int UVOffset = (row>>1) * YuvConfig->UVWidth + (col>>1);
  1323. // perform center and scale
  1324. AnyRatioFrameScale ( ppi, FrameBuffer, YuvConfig, YOffset, UVOffset );
  1325. break;
  1326. }
  1327. /*
  1328. case SCALE_TO_FIT:
  1329. // Scale the image if the aspect ratio is scalable
  1330. if ( AnyRatioFrameScale( ppi, FrameBuffer, YuvConfig, 0, 0 ) != 1 )
  1331. CenterImage ( ppi, FrameBuffer, YuvConfig );
  1332. break;
  1333. */
  1334. case CENTER:
  1335. CenterImage ( ppi, FrameBuffer, YuvConfig );
  1336. break;
  1337. default:
  1338. break;
  1339. }
  1340. }