rgb2rgb.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:97k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #ifdef _MACINTOSH
  36. #pragma require_prototypes off
  37. #endif
  38. /*** #includes: ********************************************/
  39. #include "env.h"
  40. #include "rgb.h"    /* basic RGB-data definitions & macros */
  41. #include "scale.h"  /* scale algorithms */
  42. #include "colorlib.h" /* ensure that prototypes get extern C'ed */
  43. /*** Additional pixel-level macros: ************************/
  44. /*
  45.  * Generic pixel load-convert-store macro:
  46.  */
  47. #define LOAD_CONVERT_STORE(df,d,sf,s)       
  48.     {                                       
  49.         PIXEL(df,da);                       
  50.         LOAD_CONVERT(df,da,sf,s);           
  51.         s+=BPP(sf);                         
  52.         STORE(df,d,da);                     
  53.         d+=BPP(df);                         
  54.     }
  55. /*
  56.  * Generic 4-pixels load-convert-store macro
  57.  * (XXX: this is just a lazy implementation of
  58.  *  4-times unrolled load-convert-store;
  59.  *  later, we should rewrite it for better
  60.  *  efficiency !!!)
  61.  */
  62. #define LOAD_CONVERT_STORE_4(df,d,sf,s)     
  63.     {                                       
  64.         PIXEL(df,da);                       
  65.         LOAD_CONVERT(df,da,sf,s);           
  66.         STORE(df,d,da);                     
  67.         LOAD_CONVERT(df,da,sf,s+BPP(sf));   
  68.         STORE(df,d+BPP(df),da);             
  69.         LOAD_CONVERT(df,da,sf,s+2*BPP(sf)); 
  70.         STORE(df,d+2*BPP(df),da);           
  71.         LOAD_CONVERT(df,da,sf,s+3*BPP(sf)); 
  72.         STORE(df,d+3*BPP(df),da);           
  73.         s+=4*BPP(sf);                       
  74.         d+=4*BPP(df);                       
  75.     }
  76. /*
  77.  * Generic pixel load-convert-average-store macro:
  78.  * ([d2] = convert([s]); [d12] = ([d1]+[d2])/2)
  79.  */
  80. #define LOAD_CONVERT_AVERAGE_STORE(df,d1,d12,d2,sf,s) 
  81.     {                                       
  82.         PIXEL(df,da);                       
  83.         LOAD_CONVERT(df,da,sf,s);           
  84.         s+=BPP(sf);                         
  85.         STORE(df,d2,da);                    
  86.         d2+=BPP(df);                        
  87.         LOAD_AVERAGE(df,da,da,d1);          
  88.         d1+=BPP(df);                        
  89.         STORE(df,d12,da);                   
  90.         d12+=BPP(df);                       
  91.     }
  92. /*
  93.  * Generic 4-pixels load-convert-average-store macro:
  94.  * (again, very lazy implementation; ultimately it should
  95.  *  be rewritten for all possible combinations of pixel formats !!)
  96.  */
  97. #define LOAD_CONVERT_AVERAGE_STORE_4(df,d1,d12,d2,sf,s) 
  98.     {                                       
  99.         PIXEL(df,da);                       
  100.         /* first column: */                 
  101.         LOAD_CONVERT(df,da,sf,s);           
  102.         STORE(df,d2,da);                    
  103.         LOAD_AVERAGE(df,da,da,d1);          
  104.         STORE(df,d12,da);                   
  105.         /* second column: */                
  106.         LOAD_CONVERT(df,da,sf,s+BPP(sf));   
  107.         STORE(df,d2+BPP(df),da);            
  108.         LOAD_AVERAGE(df,da,da,d1+BPP(df));  
  109.         STORE(df,d12+BPP(df),da);           
  110.         /* third column: */                 
  111.         LOAD_CONVERT(df,da,sf,s+2*BPP(sf)); 
  112.         STORE(df,d2+2*BPP(df),da);          
  113.         LOAD_AVERAGE(df,da,da,d1+2*BPP(df));
  114.         STORE(df,d12+2*BPP(df),da);         
  115.         /* fourth column: */                
  116.         LOAD_CONVERT(df,da,sf,s+3*BPP(sf)); 
  117.         STORE(df,d2+3*BPP(df),da);          
  118.         LOAD_AVERAGE(df,da,da,d1+3*BPP(df));
  119.         STORE(df,d12+3*BPP(df),da);         
  120.         /* update pointers: */              
  121.         s +=4*BPP(sf);                      
  122.         d1+=4*BPP(df);                      
  123.         d2+=4*BPP(df);                      
  124.         d12+=4*BPP(df);                     
  125.     }
  126. /*** Generic RGB single-row converters: ********************/
  127. /*
  128.  * Generic row shrinking converter:
  129.  */
  130. #define ROW_SHRINK(df,dest_ptr,dest_dx,sf,src_ptr,src_dx)   
  131.     {                                                       
  132.         /* initialize local variables: */                   
  133.         register unsigned char *d = dest_ptr;               
  134.         register unsigned char *s = src_ptr;                
  135.         register int count = dest_dx;                       
  136.         register int limit = src_dx >> 1; /* -1 */          
  137.         register int step = dest_dx;                        
  138.         /* check row length: */                             
  139.         if (count) {                                        
  140.             do {                                            
  141.                 /* convert and copy a nearest pixel: */     
  142.                 PIXEL(df,da);                               
  143.                 LOAD_CONVERT(df,da,sf,s);                   
  144.                 STORE(df,d,da);                             
  145.                 d+=BPP(df);                                 
  146.                 /* inverted Bresenham stepping: */          
  147.                 do {                                        
  148.                     /* skip source pixel: */                
  149.                     s+=BPP(sf);                             
  150.                 } while ((limit -= step) >= 0);             
  151.                 limit += src_dx;                            
  152.             } while (--count);                              
  153.         }                                                   
  154.     }
  155. /*
  156.  * Generic row copy converter:
  157.  */
  158. #define ROW_COPY(df,dest_ptr,dest_dx,sf,src_ptr,src_dx)     
  159.     {                                                       
  160.         /* do we have the same format? */                   
  161.         if (ID(df) == ID(sf)) {                             
  162.             /* just use memcopy: */                         
  163.             memcpy(dest_ptr, src_ptr, dest_dx*BPP(df)); /* Flawfinder: ignore */    
  164.         } else {                                            
  165.             /* initialize local variables: */               
  166.             register unsigned char *d = dest_ptr;           
  167.             register unsigned char *s = src_ptr;            
  168.             register int count = dest_dx;                   
  169.             /* convert misaligned pixels first: */          
  170.             while (((unsigned int)d & 3)                    
  171.                 && ((unsigned int)s & 3) && count) {        
  172.                 LOAD_CONVERT_STORE(df,d,sf,s);              
  173.                 count --;                                   
  174.             }                                               
  175.             /* the main loop (convert 4 pixels a time): */  
  176.             while (count >= 4) {                            
  177.                 LOAD_CONVERT_STORE_4(df,d,sf,s);            
  178.                 count -= 4;                                 
  179.             }                                               
  180.             /* convert the remaining pixels: */             
  181.             while (count) {                                 
  182.                 LOAD_CONVERT_STORE(df,d,sf,s);              
  183.                 count --;                                   
  184.             }                                               
  185.         }                                                   
  186.     }
  187. /*
  188.  * Generic row stretching converter:
  189.  *  (shall not be used when dest_dx/2 >= src_dx!!!)
  190.  */
  191. #define ROW_STRETCH(df,dest_ptr,dest_dx,sf,src_ptr,src_dx)  
  192.     {                                                       
  193.         /* initialize local variables: */                   
  194.         register unsigned char *d = dest_ptr;               
  195.         register unsigned char *s = src_ptr;                
  196.         register int count = dest_dx;                       
  197.         register int limit = dest_dx >> 1; /* !!! */        
  198.         register int step = src_dx;                         
  199.         /* check row length: */                             
  200.         if (count) {                                        
  201.             goto start;                                     
  202.             /* the main loop: */                            
  203.             do {                                            
  204.                 PIXEL(df,da);                               
  205.                 /* Bresenham stepping: */                   
  206.                 if ((limit -= step) < 0) {                  
  207.                     limit += dest_dx;                       
  208.                     /* load & convert pixel: */             
  209.     start:          LOAD_CONVERT(df,da,sf,s);               
  210.                     s+=BPP(sf);                             
  211.                 }                                           
  212.                 /* replicate pixel: */                      
  213.                 STORE(df,d,da);                             
  214.                 d+=BPP(df);                                 
  215.             } while (--count);                              
  216.         }                                                   
  217.     }
  218. /*
  219.  * Generic row 2x-stretching converter:
  220.  */
  221. #define ROW_STRETCH2X(df,dest_ptr,dest_dx,sf,src_ptr,src_dx) 
  222.     {                                                       
  223.         /* initialize local variables: */                   
  224.         register unsigned char *d = dest_ptr;               
  225.         register unsigned char *s = src_ptr;                
  226.         register int count = src_dx;                        
  227.         /* check row length: */                             
  228.         if (count) {                                        
  229.             /* process first integral pixel: */             
  230.             PIXEL(df,da);                                   
  231.             LOAD_CONVERT(df,da,sf,s);                       
  232.             s+=BPP(sf);                                     
  233.             count --;                                       
  234.             STORE(df,d,da);                                 
  235.             d+=BPP(df);                                     
  236.             /* main loop (process 2 pixels a time): */      
  237.             while (count >= 2) {                            
  238.                 /* load & convert second integral pixel: */ 
  239.                 PIXEL(df,db);                               
  240.                 LOAD_CONVERT(df,db,sf,s);                   
  241.                 /* calculate first half-pixel: */           
  242.                 AVERAGE(df,da,da,db);                       
  243.                 /* store both pixels: */                    
  244.                 STORE(df,d,da);                             
  245.                 STORE(df,d+BPP(df),db);                     
  246.                 /* load & convert third integral pixel: */  
  247.                 LOAD_CONVERT(df,da,sf,s+BPP(sf));           
  248.                 /* calculate second half-pixel: */          
  249.                 AVERAGE(df,db,db,da);                       
  250.                 /* store both pixels: */                    
  251.                 STORE(df,d+2*BPP(df),db);                   
  252.                 STORE(df,d+3*BPP(df),da);                   
  253.                 /* shift pointers: */                       
  254.                 s+=2*BPP(sf);                               
  255.                 d+=4*BPP(df);                               
  256.                 count -= 2;                                 
  257.             }                                               
  258.             /* is there any more pixels to convert? */      
  259.             if (count) {                                    
  260.                 /* load & convert last integral pixel: */   
  261.                 PIXEL(df,db);                               
  262.                 LOAD_CONVERT(df,db,sf,s);                   
  263.                 /* calculate last half-pixel: */            
  264.                 AVERAGE(df,da,da,db);                       
  265.                 /* store pixels: */                         
  266.                 STORE(df,d,da);                             
  267.                 STORE(df,d+BPP(df),db);                     
  268.                 STORE(df,d+2*BPP(df),db);                   
  269.             } else {                                        
  270.                 /* replicate last pixel: */                 
  271.                 STORE(df,d,da);                             
  272.             }                                               
  273.         }                                                   
  274.     }
  275. /*
  276.  * Generic row 2x+ stretching converter:
  277.  */
  278. #define ROW_STRETCH2XPLUS(df,dest_ptr,dest_dx,sf,src_ptr,src_dx) 
  279.     {                                                       
  280.         /* initialize local variables: */                   
  281.         register unsigned char *d = dest_ptr;               
  282.         register unsigned char *s = src_ptr;                
  283.         register int count = dest_dx;                       
  284.         register int limit = dest_dx >> 1; /* !!! */        
  285.         register int step = src_dx << 1;  /* !!! */         
  286.         /* # of pixels mapped outside source image: */      
  287.         register int remainder = (2*dest_dx - limit) / step;
  288.         /* check row length: */                             
  289.         if (count) {                                        
  290.             /* load & convert first pixel: */               
  291.             PIXEL(df,da); PIXEL(df,db);                     
  292.             LOAD_CONVERT(df,da,sf,s);                       
  293.             s+=BPP(sf);                                     
  294.             /* update counter: */                           
  295.             if (!(count -= remainder))                      
  296.                 goto end_of_row;                            
  297.             /* main loop: */                                
  298.             while (1) {                                     
  299.                 /* replicate first integral pixel: */       
  300.                 do {                                        
  301.                     STORE(df,d,da);                         
  302.                     d+=BPP(df);                             
  303.                     if (!(--count))                         
  304.                         goto end_of_row;                    
  305.                 } while ((limit -= step) >= 0);             
  306.                 limit += dest_dx;                           
  307.                 /* load & convert second pixel: */          
  308.                 LOAD_CONVERT(df,db,sf,s);                   
  309.                 /* calc & replicate first half-pixel: */    
  310.                 AVERAGE(df,da,da,db);                       
  311.                 do {                                        
  312.                     STORE(df,d,da);                         
  313.                     d+=BPP(df);                             
  314.                     if (!(--count))                         
  315.                         goto end_of_row;                    
  316.                 } while ((limit -= step) >= 0);             
  317.                 limit += dest_dx;                           
  318.                 /* replicate second integral pixel: */      
  319.                 do {                                        
  320.                     STORE(df,d,db);                         
  321.                     d+=BPP(df);                             
  322.                     if (!(--count))                         
  323.                         goto end_of_row_2;                  
  324.                 } while ((limit -= step) >= 0);             
  325.                 limit += dest_dx;                           
  326.                 /* load & convert third pixel: */           
  327.                 LOAD_CONVERT(df,da,sf,s+BPP(sf));           
  328.                 s+=2*BPP(sf);                               
  329.                 /* calc & replicate second half-pixel: */   
  330.                 AVERAGE(df,db,db,da);                       
  331.                 do {                                        
  332.                     STORE(df,d,db);                         
  333.                     d+=BPP(df);                             
  334.                     if (!(--count))                         
  335.                         goto end_of_row_2;                  
  336.                 } while ((limit -= step) >= 0);             
  337.                 limit += dest_dx;                           
  338.             }                                               
  339.             /* replicate the remaining pixels: */           
  340. end_of_row_2: COPY(df,da,db);                               
  341. end_of_row: while (remainder--) {                           
  342.                 STORE(df,d,da);                             
  343.                 d+=BPP(df);                                 
  344.             }                                               
  345.         }                                                   
  346.     }
  347. /*** Generic RGB 1.5-row converters: ***********************/
  348. /*
  349.  * Generic 1.5-row shrinking converter:
  350.  *  dest_ptr_1  - a previously converted row in destination image
  351.  *  dest_ptr_12 - an area to store half-pixel average row
  352.  *  dest_ptr_2  - an area to store next converted row from source image
  353.  */
  354. #define ROW2X_SHRINK(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx)   
  355.     {                                                       
  356.         /* initialize local variables: */                   
  357.         register unsigned char *d1 = dest_ptr_1;            
  358.         register unsigned char *d12 = dest_ptr_12;          
  359.         register unsigned char *d2 = dest_ptr_2;            
  360.         register unsigned char *s = src_ptr;                
  361.         register int count = dest_dx;                       
  362.         register int limit = src_dx >> 1; /* -1 */          
  363.         register int step = dest_dx;                        
  364.         /* check row length: */                             
  365.         if (count) {                                        
  366.             do {                                            
  367.                 /* load & convert pixel from second row: */ 
  368.                 PIXEL(df,da);                               
  369.                 LOAD_CONVERT(df,da,sf,s);                   
  370.                 STORE(df,d2,da);                            
  371.                 d2+=BPP(df);                                
  372.                 /* average it with pixel from first row: */ 
  373.                 LOAD_AVERAGE(df,da,da,d1);                  
  374.                 d1+=BPP(df);                                
  375.                 STORE(df,d12,da);                           
  376.                 d12+=BPP(df);                               
  377.                 /* inverted Bresenham stepping: */          
  378.                 do {                                        
  379.                     /* skip source pixel: */                
  380.                     s+=BPP(sf);                             
  381.                 } while ((limit -= step) >= 0);             
  382.                 limit += src_dx;                            
  383.             } while (--count);                              
  384.         }                                                   
  385.     }
  386. /*
  387.  * Generic 1.5-row copy converter:
  388.  */
  389. #define ROW2X_COPY(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx)     
  390.     {                                                       
  391.         /* initialize local variables: */                   
  392.         register unsigned char *d1 = dest_ptr_1;            
  393.         register unsigned char *d12 = dest_ptr_12;          
  394.         register unsigned char *d2 = dest_ptr_2;            
  395.         register unsigned char *s = src_ptr;                
  396.         register int count = dest_dx;                       
  397.         /* convert misaligned pixels first: */              
  398.         while (((unsigned int)d2 & 3)                       
  399.             && ((unsigned int)s & 3) && count) {            
  400.             LOAD_CONVERT_AVERAGE_STORE(df,d1,d12,d2,sf,s);  
  401.             count --;                                       
  402.         }                                                   
  403.         /* the main loop (convert 4 pixels a time): */      
  404.         while (count >= 4) {                                
  405.             LOAD_CONVERT_AVERAGE_STORE_4(df,d1,d12,d2,sf,s);
  406.             count -= 4;                                     
  407.         }                                                   
  408.         /* convert the remaining pixels: */                 
  409.         while (count) {                                     
  410.             LOAD_CONVERT_AVERAGE_STORE(df,d1,d12,d2,sf,s);  
  411.             count --;                                       
  412.         }                                                   
  413.     }
  414. /*
  415.  * Generic 1.5-row stretching converter:
  416.  *  (shall not be used when dest_dx/2 >= src_dx!!!)
  417.  */
  418. #define ROW2X_STRETCH(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx)  
  419.     {                                                       
  420.         /* initialize local variables: */                   
  421.         register unsigned char *d1 = dest_ptr_1;            
  422.         register unsigned char *d12 = dest_ptr_12;          
  423.         register unsigned char *d2 = dest_ptr_2;            
  424.         register unsigned char *s = src_ptr;                
  425.         register int count = dest_dx;                       
  426.         register int limit = dest_dx >> 1; /* !!! */        
  427.         register int step = src_dx;                         
  428.         /* check row length: */                             
  429.         if (count) {                                        
  430.             goto start;                                     
  431.             /* the main loop: */                            
  432.             do {                                            
  433.                 PIXEL(df,da); PIXEL(df,dc);                 
  434.                 /* Bresenham stepping: */                   
  435.                 if ((limit -= step) < 0) {                  
  436.                     limit += dest_dx;                       
  437.                     /* load & convert pixel: */             
  438.     start:          LOAD_CONVERT(df,da,sf,s);               
  439.                     s+=BPP(sf);                             
  440.                     /* calculate a half-pixel above: */     
  441.                     LOAD_AVERAGE(df,dc,da,d1);              
  442.                 }                                           
  443.                 /* replicate pixels: */                     
  444.                 d1+=BPP(df);                                
  445.                 STORE(df,d2,da);                            
  446.                 d2+=BPP(df);                                
  447.                 STORE(df,d12,dc);                           
  448.                 d12+=BPP(df);                               
  449.             } while (--count);                              
  450.         }                                                   
  451.     }
  452. /*
  453.  * Generic 1.5-row 2x-stretching converter:
  454.  */
  455. #define ROW2X_STRETCH2X(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx) 
  456.     {                                                       
  457.         /* initialize local variables: */                   
  458.         register unsigned char *d1 = dest_ptr_1;            
  459.         register unsigned char *d12 = dest_ptr_12;          
  460.         register unsigned char *d2 = dest_ptr_2;            
  461.         register unsigned char *s = src_ptr;                
  462.         register int count = src_dx;                        
  463.         /* check row length: */                             
  464.         if (count) {                                        
  465.             /* load and convert first pixel: */             
  466.             PIXEL(df,da); PIXEL(df,dc);                     
  467.             LOAD_CONVERT(df,da,sf,s);                       
  468.             s+=BPP(sf);                                     
  469.             /* calculate a half-pixel above it: */          
  470.             LOAD_AVERAGE(df,dc,da,d1);                      
  471.             d1+=2*BPP(df);                                  
  472.             count --;                                       
  473.             /* store both: */                               
  474.             STORE(df,d2,da);                                
  475.             d2+=BPP(df);                                    
  476.             STORE(df,d12,dc);                               
  477.             d12+=BPP(df);                                   
  478.             /* main loop (process 2 pixels a time): */      
  479.             while (count >= 2) {                            
  480.                 /* load & convert second integral pixel: */ 
  481.                 PIXEL(df,db); PIXEL(df,dd);                 
  482.                 LOAD_CONVERT(df,db,sf,s);                   
  483.                 /* calculate a half-pixel on the left: */   
  484.                 AVERAGE(df,da,da,db);                       
  485.                 /* store both pixels: */                    
  486.                 STORE(df,d2,da);                            
  487.                 STORE(df,d2+BPP(df),db);                    
  488.                 /* calculate a half-pixel above: */         
  489.                 LOAD_AVERAGE(df,dd,db,d1);                  
  490.                 /* calculate a half-pixel above and left: */
  491.                 AVERAGE(df,dc,dc,dd);                       
  492.                 /* store both: */                           
  493.                 STORE(df,d12,dc);                           
  494.                 STORE(df,d12+BPP(df),dd);                   
  495.                 /* load & convert third integral pixel: */  
  496.                 LOAD_CONVERT(df,da,sf,s+BPP(sf));           
  497.                 /* calculate a half-pixel on the left: */   
  498.                 AVERAGE(df,db,db,da);                       
  499.                 /* store both pixels: */                    
  500.                 STORE(df,d2+2*BPP(df),db);                  
  501.                 STORE(df,d2+3*BPP(df),da);                  
  502.                 /* calculate a half-pixel above: */         
  503.                 LOAD_AVERAGE(df,dc,da,d1+2*BPP(df));        
  504.                 /* calculate a half-pixel above and left: */
  505.                 AVERAGE(df,dd,dd,dc);                       
  506.                 /* store both: */                           
  507.                 STORE(df,d12+2*BPP(df),dd);                 
  508.                 STORE(df,d12+3*BPP(df),dc);                 
  509.                 /* shift pointers: */                       
  510.                 s+=2*BPP(sf);                               
  511.                 d1+=4*BPP(df);                              
  512.                 d2+=4*BPP(df);                              
  513.                 d12+=4*BPP(df);                             
  514.                 count -= 2;                                 
  515.             }                                               
  516.             /* is there any more pixels to convert? */      
  517.             if (count) {                                    
  518.                 /* load & convert last integral pixel: */   
  519.                 PIXEL(df,db); PIXEL(df,dd);                 
  520.                 LOAD_CONVERT(df,db,sf,s);                   
  521.                 /* calculate a half-pixel on the left: */   
  522.                 AVERAGE(df,da,da,db);                       
  523.                 /* store pixels: */                         
  524.                 STORE(df,d2,da);                            
  525.                 STORE(df,d2+BPP(df),db);                    
  526.                 STORE(df,d2+2*BPP(df),db);                  
  527.                 /* calculate a half-pixel above: */         
  528.                 LOAD_AVERAGE(df,dd,db,d1);                  
  529.                 /* calculate a half-pixel above and left: */
  530.                 AVERAGE(df,dc,dc,dd);                       
  531.                 /* store pixels: */                         
  532.                 STORE(df,d12,dc);                           
  533.                 STORE(df,d12+BPP(df),dd);                   
  534.                 STORE(df,d12+2*BPP(df),dd);                 
  535.             } else {                                        
  536.                 /* replicate last pixels: */                
  537.                 STORE(df,d2,da);                            
  538.                 STORE(df,d12,dc);                           
  539.             }                                               
  540.         }                                                   
  541.     }
  542. /*
  543.  * Generic 1.5-row 2x+ stretching converter:
  544.  */
  545. #define ROW2X_STRETCH2XPLUS(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx) 
  546.     {                                                       
  547.         /* initialize local variables: */                   
  548.         register unsigned char *d1 = dest_ptr_1;            
  549.         register unsigned char *d12 = dest_ptr_12;          
  550.         register unsigned char *d2 = dest_ptr_2;            
  551.         register unsigned char *s = src_ptr;                
  552.         register int count = dest_dx;                       
  553.         register int limit = dest_dx >> 1; /* !!! */        
  554.         register int step = src_dx << 1;  /* !!! */         
  555.         /* # of pixels mapped outside source image: */      
  556.         register int remainder = (2*dest_dx - limit) / step;
  557.         /* check row length: */                             
  558.         if (count) {                                        
  559.             /* load & convert first pixel: */               
  560.             PIXEL(df,da); PIXEL(df,db);                     
  561.             PIXEL(df,dc); PIXEL(df,dd);                     
  562.             LOAD_CONVERT(df,da,sf,s);                       
  563.             s+=BPP(sf);                                     
  564.             /* update counter: */                           
  565.             if (!(count -= remainder))                      
  566.                 goto end_of_row;                            
  567.             /* main loop: */                                
  568.             while (1) {                                     
  569.                 /* calculate a half-pixel above: */         
  570.                 LOAD_AVERAGE(df,dc,da,d1);                  
  571.                 /* replicate first pair of pixels: */       
  572.                 do {                                        
  573.                     d1+=BPP(df);                            
  574.                     STORE(df,d2,da);                        
  575.                     d2+=BPP(df);                            
  576.                     STORE(df,d12,dc);                       
  577.                     d12+=BPP(df);                           
  578.                     if (!(--count))                         
  579.                         goto end_of_row;                    
  580.                 } while ((limit -= step) >= 0);             
  581.                 limit += dest_dx;                           
  582.                 /* load & convert second pixel: */          
  583.                 LOAD_CONVERT(df,db,sf,s);                   
  584.                 /* calculate half-pixel on the left: */     
  585.                 AVERAGE(df,da,da,db);                       
  586.                 /* calculate half-pixel above and left: */  
  587.                 LOAD_AVERAGE(df,dc,da,d1);                  
  588.                 /* replicate first pair of half-pixels: */  
  589.                 do {                                        
  590.                     d1+=BPP(df);                            
  591.                     STORE(df,d2,da);                        
  592.                     d2+=BPP(df);                            
  593.                     STORE(df,d12,dc);                       
  594.                     d12+=BPP(df);                           
  595.                     if (!(--count))                         
  596.                         goto end_of_row;                    
  597.                 } while ((limit -= step) >= 0);             
  598.                 limit += dest_dx;                           
  599.                 /* calculate half-pixel above: */           
  600.                 LOAD_AVERAGE(df,dd,db,d1);                  
  601.                 /* replicate second pair of pixels: */      
  602.                 do {                                        
  603.                     d1+=BPP(df);                            
  604.                     STORE(df,d2,db);                        
  605.                     d2+=BPP(df);                            
  606.                     STORE(df,d12,dd);                       
  607.                     d12+=BPP(df);                           
  608.                     if (!(--count))                         
  609.                         goto end_of_row_2;                  
  610.                 } while ((limit -= step) >= 0);             
  611.                 limit += dest_dx;                           
  612.                 /* load & convert third pixel: */           
  613.                 LOAD_CONVERT(df,da,sf,s+BPP(sf));           
  614.                 s+=2*BPP(sf);                               
  615.                 /* calculate half-pixel on the left: */     
  616.                 AVERAGE(df,db,db,da);                       
  617.                 /* calculate half-pixel above and left: */  
  618.                 LOAD_AVERAGE(df,dd,db,d1);                  
  619.                 /* replicate second pair of half-pixels: */ 
  620.                 do {                                        
  621.                     d1+=BPP(df);                            
  622.                     STORE(df,d2,db);                        
  623.                     d2+=BPP(df);                            
  624.                     STORE(df,d12,dd);                       
  625.                     d12+=BPP(df);                           
  626.                     if (!(--count))                         
  627.                         goto end_of_row_2;                  
  628.                 } while ((limit -= step) >= 0);             
  629.                 limit += dest_dx;                           
  630.             }                                               
  631.             /* replicate the remaining pixels: */           
  632. end_of_row_2:                                               
  633.             COPY(df,da,db);                                 
  634.             COPY(df,dc,dd);                                 
  635. end_of_row: while (remainder--) {                           
  636.                 STORE(df,d2,da);                            
  637.                 d2+=BPP(df);                                
  638.                 STORE(df,d12,dc);                           
  639.                 d12+=BPP(df);                               
  640.             }                                               
  641.         }                                                   
  642.     }
  643. /***********************************************************/
  644. /*
  645.  * Function names:
  646.  */
  647. #define FN(df,sf)           sf##to##df
  648. #define ROW_FN(df,sf,t)     sf##to##df##_ROW_##t
  649. #define ROW2X_FN(df,sf,t)   sf##to##df##_ROW2X_##t
  650. /*
  651.  * Function replication macros:
  652.  *  (row- and 1.5 row- converters)
  653.  */
  654. #define ROW_FUNC(df,sf,t)   
  655.     void ROW_FN(df,sf,t) (unsigned char *dest_ptr,          
  656.         int dest_dx, unsigned char *src_ptr, int src_dx)    
  657.         ROW_##t(df,dest_ptr,dest_dx,sf,src_ptr,src_dx)
  658. #define ROW2X_FUNC(df,sf,t) 
  659.     void ROW2X_FN(df,sf,t) (unsigned char *dest_ptr_1,      
  660.         unsigned char *dest_ptr_12, unsigned char *dest_ptr_2,
  661.         int dest_dx, unsigned char *src_ptr, int src_dx)    
  662.         ROW2X_##t(df,dest_ptr_1,dest_ptr_12,dest_ptr_2,dest_dx,sf,src_ptr,src_dx)
  663. /***********************************************************/
  664. /*
  665.  * Actual row functions:
  666.  */
  667. ROW_FUNC(RGB32 ,RGB32 ,SHRINK)
  668. ROW_FUNC(RGB32 ,RGB32 ,COPY)
  669. ROW_FUNC(RGB32 ,RGB32 ,STRETCH)
  670. ROW_FUNC(RGB32 ,RGB32 ,STRETCH2X)
  671. ROW_FUNC(RGB32 ,RGB32 ,STRETCH2XPLUS)
  672. ROW_FUNC(RGB32 ,BGR32 ,SHRINK)
  673. ROW_FUNC(RGB32 ,BGR32 ,COPY)
  674. ROW_FUNC(RGB32 ,BGR32 ,STRETCH)
  675. ROW_FUNC(RGB32 ,BGR32 ,STRETCH2X)
  676. ROW_FUNC(RGB32 ,BGR32 ,STRETCH2XPLUS)
  677. ROW_FUNC(RGB32 ,RGB24 ,SHRINK)
  678. ROW_FUNC(RGB32 ,RGB24 ,COPY)
  679. ROW_FUNC(RGB32 ,RGB24 ,STRETCH)
  680. ROW_FUNC(RGB32 ,RGB24 ,STRETCH2X)
  681. ROW_FUNC(RGB32 ,RGB24 ,STRETCH2XPLUS)
  682. ROW_FUNC(RGB32 ,RGB565,SHRINK)
  683. ROW_FUNC(RGB32 ,RGB565,COPY)
  684. ROW_FUNC(RGB32 ,RGB565,STRETCH)
  685. ROW_FUNC(RGB32 ,RGB565,STRETCH2X)
  686. ROW_FUNC(RGB32 ,RGB565,STRETCH2XPLUS)
  687. ROW_FUNC(RGB32 ,RGB555,SHRINK)
  688. ROW_FUNC(RGB32 ,RGB555,COPY)
  689. ROW_FUNC(RGB32 ,RGB555,STRETCH)
  690. ROW_FUNC(RGB32 ,RGB555,STRETCH2X)
  691. ROW_FUNC(RGB32 ,RGB555,STRETCH2XPLUS)
  692. ROW_FUNC(RGB32 ,RGB8  ,SHRINK)
  693. ROW_FUNC(RGB32 ,RGB8  ,COPY)
  694. ROW_FUNC(RGB32 ,RGB8  ,STRETCH)
  695. ROW_FUNC(RGB32 ,RGB8  ,STRETCH2X)
  696. ROW_FUNC(RGB32 ,RGB8  ,STRETCH2XPLUS)
  697. ROW_FUNC(BGR32 ,RGB32 ,SHRINK)
  698. ROW_FUNC(BGR32 ,RGB32 ,COPY)
  699. ROW_FUNC(BGR32 ,RGB32 ,STRETCH)
  700. ROW_FUNC(BGR32 ,RGB32 ,STRETCH2X)
  701. ROW_FUNC(BGR32 ,RGB32 ,STRETCH2XPLUS)
  702. ROW_FUNC(BGR32 ,BGR32 ,SHRINK)
  703. ROW_FUNC(BGR32 ,BGR32 ,COPY)
  704. ROW_FUNC(BGR32 ,BGR32 ,STRETCH)
  705. ROW_FUNC(BGR32 ,BGR32 ,STRETCH2X)
  706. ROW_FUNC(BGR32 ,BGR32 ,STRETCH2XPLUS)
  707. ROW_FUNC(BGR32 ,RGB24 ,SHRINK)
  708. ROW_FUNC(BGR32 ,RGB24 ,COPY)
  709. ROW_FUNC(BGR32 ,RGB24 ,STRETCH)
  710. ROW_FUNC(BGR32 ,RGB24 ,STRETCH2X)
  711. ROW_FUNC(BGR32 ,RGB24 ,STRETCH2XPLUS)
  712. ROW_FUNC(BGR32 ,RGB565,SHRINK)
  713. ROW_FUNC(BGR32 ,RGB565,COPY)
  714. ROW_FUNC(BGR32 ,RGB565,STRETCH)
  715. ROW_FUNC(BGR32 ,RGB565,STRETCH2X)
  716. ROW_FUNC(BGR32 ,RGB565,STRETCH2XPLUS)
  717. ROW_FUNC(BGR32 ,RGB555,SHRINK)
  718. ROW_FUNC(BGR32 ,RGB555,COPY)
  719. ROW_FUNC(BGR32 ,RGB555,STRETCH)
  720. ROW_FUNC(BGR32 ,RGB555,STRETCH2X)
  721. ROW_FUNC(BGR32 ,RGB555,STRETCH2XPLUS)
  722. ROW_FUNC(BGR32 ,RGB8  ,SHRINK)
  723. ROW_FUNC(BGR32 ,RGB8  ,COPY)
  724. ROW_FUNC(BGR32 ,RGB8  ,STRETCH)
  725. ROW_FUNC(BGR32 ,RGB8  ,STRETCH2X)
  726. ROW_FUNC(BGR32 ,RGB8  ,STRETCH2XPLUS)
  727. ROW_FUNC(RGB24 ,RGB32 ,SHRINK)
  728. ROW_FUNC(RGB24 ,RGB32 ,COPY)
  729. ROW_FUNC(RGB24 ,RGB32 ,STRETCH)
  730. ROW_FUNC(RGB24 ,RGB32 ,STRETCH2X)
  731. ROW_FUNC(RGB24 ,RGB32 ,STRETCH2XPLUS)
  732. ROW_FUNC(RGB24 ,BGR32 ,SHRINK)
  733. ROW_FUNC(RGB24 ,BGR32 ,COPY)
  734. ROW_FUNC(RGB24 ,BGR32 ,STRETCH)
  735. ROW_FUNC(RGB24 ,BGR32 ,STRETCH2X)
  736. ROW_FUNC(RGB24 ,BGR32 ,STRETCH2XPLUS)
  737. ROW_FUNC(RGB24 ,RGB24 ,SHRINK)
  738. ROW_FUNC(RGB24 ,RGB24 ,COPY)
  739. ROW_FUNC(RGB24 ,RGB24 ,STRETCH)
  740. ROW_FUNC(RGB24 ,RGB24 ,STRETCH2X)
  741. ROW_FUNC(RGB24 ,RGB24 ,STRETCH2XPLUS)
  742. ROW_FUNC(RGB24 ,RGB565,SHRINK)
  743. ROW_FUNC(RGB24 ,RGB565,COPY)
  744. ROW_FUNC(RGB24 ,RGB565,STRETCH)
  745. ROW_FUNC(RGB24 ,RGB565,STRETCH2X)
  746. ROW_FUNC(RGB24 ,RGB565,STRETCH2XPLUS)
  747. ROW_FUNC(RGB24 ,RGB555,SHRINK)
  748. ROW_FUNC(RGB24 ,RGB555,COPY)
  749. ROW_FUNC(RGB24 ,RGB555,STRETCH)
  750. ROW_FUNC(RGB24 ,RGB555,STRETCH2X)
  751. ROW_FUNC(RGB24 ,RGB555,STRETCH2XPLUS)
  752. ROW_FUNC(RGB24 ,RGB8  ,SHRINK)
  753. ROW_FUNC(RGB24 ,RGB8  ,COPY)
  754. ROW_FUNC(RGB24 ,RGB8  ,STRETCH)
  755. ROW_FUNC(RGB24 ,RGB8  ,STRETCH2X)
  756. ROW_FUNC(RGB24 ,RGB8  ,STRETCH2XPLUS)
  757. ROW_FUNC(RGB565,RGB32 ,SHRINK)
  758. ROW_FUNC(RGB565,RGB32 ,COPY)
  759. ROW_FUNC(RGB565,RGB32 ,STRETCH)
  760. ROW_FUNC(RGB565,RGB32 ,STRETCH2X)
  761. ROW_FUNC(RGB565,RGB32 ,STRETCH2XPLUS)
  762. ROW_FUNC(RGB565,BGR32 ,SHRINK)
  763. ROW_FUNC(RGB565,BGR32 ,COPY)
  764. ROW_FUNC(RGB565,BGR32 ,STRETCH)
  765. ROW_FUNC(RGB565,BGR32 ,STRETCH2X)
  766. ROW_FUNC(RGB565,BGR32 ,STRETCH2XPLUS)
  767. ROW_FUNC(RGB565,RGB24 ,SHRINK)
  768. ROW_FUNC(RGB565,RGB24 ,COPY)
  769. ROW_FUNC(RGB565,RGB24 ,STRETCH)
  770. ROW_FUNC(RGB565,RGB24 ,STRETCH2X)
  771. ROW_FUNC(RGB565,RGB24 ,STRETCH2XPLUS)
  772. ROW_FUNC(RGB565,RGB565,SHRINK)
  773. ROW_FUNC(RGB565,RGB565,COPY)
  774. ROW_FUNC(RGB565,RGB565,STRETCH)
  775. ROW_FUNC(RGB565,RGB565,STRETCH2X)
  776. ROW_FUNC(RGB565,RGB565,STRETCH2XPLUS)
  777. ROW_FUNC(RGB565,RGB555,SHRINK)
  778. ROW_FUNC(RGB565,RGB555,COPY)
  779. ROW_FUNC(RGB565,RGB555,STRETCH)
  780. ROW_FUNC(RGB565,RGB555,STRETCH2X)
  781. ROW_FUNC(RGB565,RGB555,STRETCH2XPLUS)
  782. ROW_FUNC(RGB565,RGB8  ,SHRINK)
  783. ROW_FUNC(RGB565,RGB8  ,COPY)
  784. ROW_FUNC(RGB565,RGB8  ,STRETCH)
  785. ROW_FUNC(RGB565,RGB8  ,STRETCH2X)
  786. ROW_FUNC(RGB565,RGB8  ,STRETCH2XPLUS)
  787. ROW_FUNC(RGB555,RGB32 ,SHRINK)
  788. ROW_FUNC(RGB555,RGB32 ,COPY)
  789. ROW_FUNC(RGB555,RGB32 ,STRETCH)
  790. ROW_FUNC(RGB555,RGB32 ,STRETCH2X)
  791. ROW_FUNC(RGB555,RGB32 ,STRETCH2XPLUS)
  792. ROW_FUNC(RGB555,BGR32 ,SHRINK)
  793. ROW_FUNC(RGB555,BGR32 ,COPY)
  794. ROW_FUNC(RGB555,BGR32 ,STRETCH)
  795. ROW_FUNC(RGB555,BGR32 ,STRETCH2X)
  796. ROW_FUNC(RGB555,BGR32 ,STRETCH2XPLUS)
  797. ROW_FUNC(RGB555,RGB24 ,SHRINK)
  798. ROW_FUNC(RGB555,RGB24 ,COPY)
  799. ROW_FUNC(RGB555,RGB24 ,STRETCH)
  800. ROW_FUNC(RGB555,RGB24 ,STRETCH2X)
  801. ROW_FUNC(RGB555,RGB24 ,STRETCH2XPLUS)
  802. ROW_FUNC(RGB555,RGB565,SHRINK)
  803. ROW_FUNC(RGB555,RGB565,COPY)
  804. ROW_FUNC(RGB555,RGB565,STRETCH)
  805. ROW_FUNC(RGB555,RGB565,STRETCH2X)
  806. ROW_FUNC(RGB555,RGB565,STRETCH2XPLUS)
  807. ROW_FUNC(RGB555,RGB555,SHRINK)
  808. ROW_FUNC(RGB555,RGB555,COPY)
  809. ROW_FUNC(RGB555,RGB555,STRETCH)
  810. ROW_FUNC(RGB555,RGB555,STRETCH2X)
  811. ROW_FUNC(RGB555,RGB555,STRETCH2XPLUS)
  812. ROW_FUNC(RGB555,RGB8  ,SHRINK)
  813. ROW_FUNC(RGB555,RGB8  ,COPY)
  814. ROW_FUNC(RGB555,RGB8  ,STRETCH)
  815. ROW_FUNC(RGB555,RGB8  ,STRETCH2X)
  816. ROW_FUNC(RGB555,RGB8  ,STRETCH2XPLUS)
  817. ROW_FUNC(RGB8  ,RGB32 ,SHRINK)
  818. ROW_FUNC(RGB8  ,RGB32 ,COPY)
  819. ROW_FUNC(RGB8  ,RGB32 ,STRETCH)
  820. ROW_FUNC(RGB8  ,RGB32 ,STRETCH2X)
  821. ROW_FUNC(RGB8  ,RGB32 ,STRETCH2XPLUS)
  822. ROW_FUNC(RGB8  ,BGR32 ,SHRINK)
  823. ROW_FUNC(RGB8  ,BGR32 ,COPY)
  824. ROW_FUNC(RGB8  ,BGR32 ,STRETCH)
  825. ROW_FUNC(RGB8  ,BGR32 ,STRETCH2X)
  826. ROW_FUNC(RGB8  ,BGR32 ,STRETCH2XPLUS)
  827. ROW_FUNC(RGB8  ,RGB24 ,SHRINK)
  828. ROW_FUNC(RGB8  ,RGB24 ,COPY)
  829. ROW_FUNC(RGB8  ,RGB24 ,STRETCH)
  830. ROW_FUNC(RGB8  ,RGB24 ,STRETCH2X)
  831. ROW_FUNC(RGB8  ,RGB24 ,STRETCH2XPLUS)
  832. ROW_FUNC(RGB8  ,RGB565,SHRINK)
  833. ROW_FUNC(RGB8  ,RGB565,COPY)
  834. ROW_FUNC(RGB8  ,RGB565,STRETCH)
  835. ROW_FUNC(RGB8  ,RGB565,STRETCH2X)
  836. ROW_FUNC(RGB8  ,RGB565,STRETCH2XPLUS)
  837. ROW_FUNC(RGB8  ,RGB555,SHRINK)
  838. ROW_FUNC(RGB8  ,RGB555,COPY)
  839. ROW_FUNC(RGB8  ,RGB555,STRETCH)
  840. ROW_FUNC(RGB8  ,RGB555,STRETCH2X)
  841. ROW_FUNC(RGB8  ,RGB555,STRETCH2XPLUS)
  842. ROW_FUNC(RGB8  ,RGB8  ,SHRINK)
  843. ROW_FUNC(RGB8  ,RGB8  ,COPY)
  844. ROW_FUNC(RGB8  ,RGB8  ,STRETCH)
  845. ROW_FUNC(RGB8  ,RGB8  ,STRETCH2X)
  846. ROW_FUNC(RGB8  ,RGB8  ,STRETCH2XPLUS)
  847. /*
  848.  * Actual 1.5-row conversion functions:
  849.  */
  850. ROW2X_FUNC(RGB32 ,RGB32 ,SHRINK)
  851. ROW2X_FUNC(RGB32 ,RGB32 ,COPY)
  852. ROW2X_FUNC(RGB32 ,RGB32 ,STRETCH)
  853. ROW2X_FUNC(RGB32 ,RGB32 ,STRETCH2X)
  854. ROW2X_FUNC(RGB32 ,RGB32 ,STRETCH2XPLUS)
  855. ROW2X_FUNC(RGB32 ,BGR32 ,SHRINK)
  856. ROW2X_FUNC(RGB32 ,BGR32 ,COPY)
  857. ROW2X_FUNC(RGB32 ,BGR32 ,STRETCH)
  858. ROW2X_FUNC(RGB32 ,BGR32 ,STRETCH2X)
  859. ROW2X_FUNC(RGB32 ,BGR32 ,STRETCH2XPLUS)
  860. ROW2X_FUNC(RGB32 ,RGB24 ,SHRINK)
  861. ROW2X_FUNC(RGB32 ,RGB24 ,COPY)
  862. ROW2X_FUNC(RGB32 ,RGB24 ,STRETCH)
  863. ROW2X_FUNC(RGB32 ,RGB24 ,STRETCH2X)
  864. ROW2X_FUNC(RGB32 ,RGB24 ,STRETCH2XPLUS)
  865. ROW2X_FUNC(RGB32 ,RGB565,SHRINK)
  866. ROW2X_FUNC(RGB32 ,RGB565,COPY)
  867. ROW2X_FUNC(RGB32 ,RGB565,STRETCH)
  868. ROW2X_FUNC(RGB32 ,RGB565,STRETCH2X)
  869. ROW2X_FUNC(RGB32 ,RGB565,STRETCH2XPLUS)
  870. ROW2X_FUNC(RGB32 ,RGB555,SHRINK)
  871. ROW2X_FUNC(RGB32 ,RGB555,COPY)
  872. ROW2X_FUNC(RGB32 ,RGB555,STRETCH)
  873. ROW2X_FUNC(RGB32 ,RGB555,STRETCH2X)
  874. ROW2X_FUNC(RGB32 ,RGB555,STRETCH2XPLUS)
  875. ROW2X_FUNC(RGB32 ,RGB8  ,SHRINK)
  876. ROW2X_FUNC(RGB32 ,RGB8  ,COPY)
  877. ROW2X_FUNC(RGB32 ,RGB8  ,STRETCH)
  878. ROW2X_FUNC(RGB32 ,RGB8  ,STRETCH2X)
  879. ROW2X_FUNC(RGB32 ,RGB8  ,STRETCH2XPLUS)
  880. ROW2X_FUNC(BGR32 ,RGB32 ,SHRINK)
  881. ROW2X_FUNC(BGR32 ,RGB32 ,COPY)
  882. ROW2X_FUNC(BGR32 ,RGB32 ,STRETCH)
  883. ROW2X_FUNC(BGR32 ,RGB32 ,STRETCH2X)
  884. ROW2X_FUNC(BGR32 ,RGB32 ,STRETCH2XPLUS)
  885. ROW2X_FUNC(BGR32 ,BGR32 ,SHRINK)
  886. ROW2X_FUNC(BGR32 ,BGR32 ,COPY)
  887. ROW2X_FUNC(BGR32 ,BGR32 ,STRETCH)
  888. ROW2X_FUNC(BGR32 ,BGR32 ,STRETCH2X)
  889. ROW2X_FUNC(BGR32 ,BGR32 ,STRETCH2XPLUS)
  890. ROW2X_FUNC(BGR32 ,RGB24 ,SHRINK)
  891. ROW2X_FUNC(BGR32 ,RGB24 ,COPY)
  892. ROW2X_FUNC(BGR32 ,RGB24 ,STRETCH)
  893. ROW2X_FUNC(BGR32 ,RGB24 ,STRETCH2X)
  894. ROW2X_FUNC(BGR32 ,RGB24 ,STRETCH2XPLUS)
  895. ROW2X_FUNC(BGR32 ,RGB565,SHRINK)
  896. ROW2X_FUNC(BGR32 ,RGB565,COPY)
  897. ROW2X_FUNC(BGR32 ,RGB565,STRETCH)
  898. ROW2X_FUNC(BGR32 ,RGB565,STRETCH2X)
  899. ROW2X_FUNC(BGR32 ,RGB565,STRETCH2XPLUS)
  900. ROW2X_FUNC(BGR32 ,RGB555,SHRINK)
  901. ROW2X_FUNC(BGR32 ,RGB555,COPY)
  902. ROW2X_FUNC(BGR32 ,RGB555,STRETCH)
  903. ROW2X_FUNC(BGR32 ,RGB555,STRETCH2X)
  904. ROW2X_FUNC(BGR32 ,RGB555,STRETCH2XPLUS)
  905. ROW2X_FUNC(BGR32 ,RGB8  ,SHRINK)
  906. ROW2X_FUNC(BGR32 ,RGB8  ,COPY)
  907. ROW2X_FUNC(BGR32 ,RGB8  ,STRETCH)
  908. ROW2X_FUNC(BGR32 ,RGB8  ,STRETCH2X)
  909. ROW2X_FUNC(BGR32 ,RGB8  ,STRETCH2XPLUS)
  910. ROW2X_FUNC(RGB24 ,RGB32 ,SHRINK)
  911. ROW2X_FUNC(RGB24 ,RGB32 ,COPY)
  912. ROW2X_FUNC(RGB24 ,RGB32 ,STRETCH)
  913. ROW2X_FUNC(RGB24 ,RGB32 ,STRETCH2X)
  914. ROW2X_FUNC(RGB24 ,RGB32 ,STRETCH2XPLUS)
  915. ROW2X_FUNC(RGB24 ,BGR32 ,SHRINK)
  916. ROW2X_FUNC(RGB24 ,BGR32 ,COPY)
  917. ROW2X_FUNC(RGB24 ,BGR32 ,STRETCH)
  918. ROW2X_FUNC(RGB24 ,BGR32 ,STRETCH2X)
  919. ROW2X_FUNC(RGB24 ,BGR32 ,STRETCH2XPLUS)
  920. ROW2X_FUNC(RGB24 ,RGB24 ,SHRINK)
  921. ROW2X_FUNC(RGB24 ,RGB24 ,COPY)
  922. ROW2X_FUNC(RGB24 ,RGB24 ,STRETCH)
  923. ROW2X_FUNC(RGB24 ,RGB24 ,STRETCH2X)
  924. ROW2X_FUNC(RGB24 ,RGB24 ,STRETCH2XPLUS)
  925. ROW2X_FUNC(RGB24 ,RGB565,SHRINK)
  926. ROW2X_FUNC(RGB24 ,RGB565,COPY)
  927. ROW2X_FUNC(RGB24 ,RGB565,STRETCH)
  928. ROW2X_FUNC(RGB24 ,RGB565,STRETCH2X)
  929. ROW2X_FUNC(RGB24 ,RGB565,STRETCH2XPLUS)
  930. ROW2X_FUNC(RGB24 ,RGB555,SHRINK)
  931. ROW2X_FUNC(RGB24 ,RGB555,COPY)
  932. ROW2X_FUNC(RGB24 ,RGB555,STRETCH)
  933. ROW2X_FUNC(RGB24 ,RGB555,STRETCH2X)
  934. ROW2X_FUNC(RGB24 ,RGB555,STRETCH2XPLUS)
  935. ROW2X_FUNC(RGB24 ,RGB8  ,SHRINK)
  936. ROW2X_FUNC(RGB24 ,RGB8  ,COPY)
  937. ROW2X_FUNC(RGB24 ,RGB8  ,STRETCH)
  938. ROW2X_FUNC(RGB24 ,RGB8  ,STRETCH2X)
  939. ROW2X_FUNC(RGB24 ,RGB8  ,STRETCH2XPLUS)
  940. ROW2X_FUNC(RGB565,RGB32 ,SHRINK)
  941. ROW2X_FUNC(RGB565,RGB32 ,COPY)
  942. ROW2X_FUNC(RGB565,RGB32 ,STRETCH)
  943. ROW2X_FUNC(RGB565,RGB32 ,STRETCH2X)
  944. ROW2X_FUNC(RGB565,RGB32 ,STRETCH2XPLUS)
  945. ROW2X_FUNC(RGB565,BGR32 ,SHRINK)
  946. ROW2X_FUNC(RGB565,BGR32 ,COPY)
  947. ROW2X_FUNC(RGB565,BGR32 ,STRETCH)
  948. ROW2X_FUNC(RGB565,BGR32 ,STRETCH2X)
  949. ROW2X_FUNC(RGB565,BGR32 ,STRETCH2XPLUS)
  950. ROW2X_FUNC(RGB565,RGB24 ,SHRINK)
  951. ROW2X_FUNC(RGB565,RGB24 ,COPY)
  952. ROW2X_FUNC(RGB565,RGB24 ,STRETCH)
  953. ROW2X_FUNC(RGB565,RGB24 ,STRETCH2X)
  954. ROW2X_FUNC(RGB565,RGB24 ,STRETCH2XPLUS)
  955. ROW2X_FUNC(RGB565,RGB565,SHRINK)
  956. ROW2X_FUNC(RGB565,RGB565,COPY)
  957. ROW2X_FUNC(RGB565,RGB565,STRETCH)
  958. ROW2X_FUNC(RGB565,RGB565,STRETCH2X)
  959. ROW2X_FUNC(RGB565,RGB565,STRETCH2XPLUS)
  960. ROW2X_FUNC(RGB565,RGB555,SHRINK)
  961. ROW2X_FUNC(RGB565,RGB555,COPY)
  962. ROW2X_FUNC(RGB565,RGB555,STRETCH)
  963. ROW2X_FUNC(RGB565,RGB555,STRETCH2X)
  964. ROW2X_FUNC(RGB565,RGB555,STRETCH2XPLUS)
  965. ROW2X_FUNC(RGB565,RGB8  ,SHRINK)
  966. ROW2X_FUNC(RGB565,RGB8  ,COPY)
  967. ROW2X_FUNC(RGB565,RGB8  ,STRETCH)
  968. ROW2X_FUNC(RGB565,RGB8  ,STRETCH2X)
  969. ROW2X_FUNC(RGB565,RGB8  ,STRETCH2XPLUS)
  970. ROW2X_FUNC(RGB555,RGB32 ,SHRINK)
  971. ROW2X_FUNC(RGB555,RGB32 ,COPY)
  972. ROW2X_FUNC(RGB555,RGB32 ,STRETCH)
  973. ROW2X_FUNC(RGB555,RGB32 ,STRETCH2X)
  974. ROW2X_FUNC(RGB555,RGB32 ,STRETCH2XPLUS)
  975. ROW2X_FUNC(RGB555,BGR32 ,SHRINK)
  976. ROW2X_FUNC(RGB555,BGR32 ,COPY)
  977. ROW2X_FUNC(RGB555,BGR32 ,STRETCH)
  978. ROW2X_FUNC(RGB555,BGR32 ,STRETCH2X)
  979. ROW2X_FUNC(RGB555,BGR32 ,STRETCH2XPLUS)
  980. ROW2X_FUNC(RGB555,RGB24 ,SHRINK)
  981. ROW2X_FUNC(RGB555,RGB24 ,COPY)
  982. ROW2X_FUNC(RGB555,RGB24 ,STRETCH)
  983. ROW2X_FUNC(RGB555,RGB24 ,STRETCH2X)
  984. ROW2X_FUNC(RGB555,RGB24 ,STRETCH2XPLUS)
  985. ROW2X_FUNC(RGB555,RGB565,SHRINK)
  986. ROW2X_FUNC(RGB555,RGB565,COPY)
  987. ROW2X_FUNC(RGB555,RGB565,STRETCH)
  988. ROW2X_FUNC(RGB555,RGB565,STRETCH2X)
  989. ROW2X_FUNC(RGB555,RGB565,STRETCH2XPLUS)
  990. ROW2X_FUNC(RGB555,RGB555,SHRINK)
  991. ROW2X_FUNC(RGB555,RGB555,COPY)
  992. ROW2X_FUNC(RGB555,RGB555,STRETCH)
  993. ROW2X_FUNC(RGB555,RGB555,STRETCH2X)
  994. ROW2X_FUNC(RGB555,RGB555,STRETCH2XPLUS)
  995. ROW2X_FUNC(RGB555,RGB8  ,SHRINK)
  996. ROW2X_FUNC(RGB555,RGB8  ,COPY)
  997. ROW2X_FUNC(RGB555,RGB8  ,STRETCH)
  998. ROW2X_FUNC(RGB555,RGB8  ,STRETCH2X)
  999. ROW2X_FUNC(RGB555,RGB8  ,STRETCH2XPLUS)
  1000. ROW2X_FUNC(RGB8  ,RGB32 ,SHRINK)
  1001. ROW2X_FUNC(RGB8  ,RGB32 ,COPY)
  1002. ROW2X_FUNC(RGB8  ,RGB32 ,STRETCH)
  1003. ROW2X_FUNC(RGB8  ,RGB32 ,STRETCH2X)
  1004. ROW2X_FUNC(RGB8  ,RGB32 ,STRETCH2XPLUS)
  1005. ROW2X_FUNC(RGB8  ,BGR32 ,SHRINK)
  1006. ROW2X_FUNC(RGB8  ,BGR32 ,COPY)
  1007. ROW2X_FUNC(RGB8  ,BGR32 ,STRETCH)
  1008. ROW2X_FUNC(RGB8  ,BGR32 ,STRETCH2X)
  1009. ROW2X_FUNC(RGB8  ,BGR32 ,STRETCH2XPLUS)
  1010. ROW2X_FUNC(RGB8  ,RGB24 ,SHRINK)
  1011. ROW2X_FUNC(RGB8  ,RGB24 ,COPY)
  1012. ROW2X_FUNC(RGB8  ,RGB24 ,STRETCH)
  1013. ROW2X_FUNC(RGB8  ,RGB24 ,STRETCH2X)
  1014. ROW2X_FUNC(RGB8  ,RGB24 ,STRETCH2XPLUS)
  1015. ROW2X_FUNC(RGB8  ,RGB565,SHRINK)
  1016. ROW2X_FUNC(RGB8  ,RGB565,COPY)
  1017. ROW2X_FUNC(RGB8  ,RGB565,STRETCH)
  1018. ROW2X_FUNC(RGB8  ,RGB565,STRETCH2X)
  1019. ROW2X_FUNC(RGB8  ,RGB565,STRETCH2XPLUS)
  1020. ROW2X_FUNC(RGB8  ,RGB555,SHRINK)
  1021. ROW2X_FUNC(RGB8  ,RGB555,COPY)
  1022. ROW2X_FUNC(RGB8  ,RGB555,STRETCH)
  1023. ROW2X_FUNC(RGB8  ,RGB555,STRETCH2X)
  1024. ROW2X_FUNC(RGB8  ,RGB555,STRETCH2XPLUS)
  1025. ROW2X_FUNC(RGB8  ,RGB8  ,SHRINK)
  1026. ROW2X_FUNC(RGB8  ,RGB8  ,COPY)
  1027. ROW2X_FUNC(RGB8  ,RGB8  ,STRETCH)
  1028. ROW2X_FUNC(RGB8  ,RGB8  ,STRETCH2X)
  1029. ROW2X_FUNC(RGB8  ,RGB8  ,STRETCH2XPLUS)
  1030. /*
  1031.  * Row scale function selection tables:
  1032.  *  [destination format][source format][row scale type]
  1033.  */
  1034. void (* RowFuncs [RGB_FORMATS][RGB_FORMATS][SCALE_FUNCS]) (
  1035.     unsigned char *dest_ptr, int dest_dx, unsigned char *src_ptr, int src_dx) =
  1036. {
  1037.     {   {
  1038.             ROW_FN(RGB32 ,RGB32 ,SHRINK),
  1039.             ROW_FN(RGB32 ,RGB32 ,COPY),
  1040.             ROW_FN(RGB32 ,RGB32 ,STRETCH),
  1041.             ROW_FN(RGB32 ,RGB32 ,STRETCH2X),
  1042.             ROW_FN(RGB32 ,RGB32 ,STRETCH2XPLUS)
  1043.         },{
  1044. #ifdef _FAT_HXCOLOR
  1045.             ROW_FN(RGB32 ,BGR32 ,SHRINK),
  1046.             ROW_FN(RGB32 ,BGR32 ,COPY),
  1047.             ROW_FN(RGB32 ,BGR32 ,STRETCH),
  1048.             ROW_FN(RGB32 ,BGR32 ,STRETCH2X),
  1049.             ROW_FN(RGB32 ,BGR32 ,STRETCH2XPLUS)
  1050. #else
  1051.     0,
  1052.     0,
  1053.     0,
  1054.             0,
  1055.             0
  1056. #endif
  1057.         },{
  1058. #ifdef _FAT_HXCOLOR
  1059.             ROW_FN(RGB32 ,RGB24 ,SHRINK),
  1060.             ROW_FN(RGB32 ,RGB24 ,COPY),
  1061.             ROW_FN(RGB32 ,RGB24 ,STRETCH),
  1062.             ROW_FN(RGB32 ,RGB24 ,STRETCH2X),
  1063.             ROW_FN(RGB32 ,RGB24 ,STRETCH2XPLUS)
  1064. #else
  1065.     0,
  1066.     0,
  1067.             0,
  1068.             0,
  1069.     0
  1070. #endif
  1071.         },{
  1072. #ifdef _FAT_HXCOLOR
  1073.             ROW_FN(RGB32 ,RGB565,SHRINK),
  1074.             ROW_FN(RGB32 ,RGB565,COPY),
  1075.             ROW_FN(RGB32 ,RGB565,STRETCH),
  1076.             ROW_FN(RGB32 ,RGB565,STRETCH2X),
  1077.             ROW_FN(RGB32 ,RGB565,STRETCH2XPLUS)
  1078. #else
  1079.     0,
  1080.     0,
  1081.     0,
  1082.             0,
  1083.             0
  1084. #endif
  1085.         },{
  1086. #ifdef _FAT_HXCOLOR
  1087.             ROW_FN(RGB32 ,RGB555,SHRINK),
  1088.             ROW_FN(RGB32 ,RGB555,COPY),
  1089.             ROW_FN(RGB32 ,RGB555,STRETCH),
  1090.             ROW_FN(RGB32 ,RGB555,STRETCH2X),
  1091.             ROW_FN(RGB32 ,RGB555,STRETCH2XPLUS)
  1092. #else
  1093.     0,
  1094.     0,
  1095.     0,
  1096.             0,
  1097.             0
  1098. #endif
  1099.         },{ /* rgb444 stub */
  1100.             0,
  1101.             0,
  1102.             0,
  1103.             0,
  1104.             0
  1105.         },{
  1106. #ifdef _8_BIT_SUPPORT
  1107.             ROW_FN(RGB32 ,RGB8  ,SHRINK),
  1108.             ROW_FN(RGB32 ,RGB8  ,COPY),
  1109.             ROW_FN(RGB32 ,RGB8  ,STRETCH),
  1110.             ROW_FN(RGB32 ,RGB8  ,STRETCH2X),
  1111.             ROW_FN(RGB32 ,RGB8  ,STRETCH2XPLUS)
  1112. #else
  1113.     0,
  1114.     0,
  1115.     0,
  1116.             0,
  1117.             0
  1118. #endif
  1119.         }
  1120.     },{ {
  1121.             ROW_FN(BGR32 ,RGB32 ,SHRINK),
  1122.             ROW_FN(BGR32 ,RGB32 ,COPY),
  1123.             ROW_FN(BGR32 ,RGB32 ,STRETCH),
  1124.             ROW_FN(BGR32 ,RGB32 ,STRETCH2X),
  1125.             ROW_FN(BGR32 ,RGB32 ,STRETCH2XPLUS)
  1126.         },{
  1127. #ifdef _FAT_HXCOLOR
  1128.             ROW_FN(BGR32 ,BGR32 ,SHRINK),
  1129.             ROW_FN(BGR32 ,BGR32 ,COPY),
  1130.             ROW_FN(BGR32 ,BGR32 ,STRETCH),
  1131.             ROW_FN(BGR32 ,BGR32 ,STRETCH2X),
  1132.             ROW_FN(BGR32 ,BGR32 ,STRETCH2XPLUS)
  1133. #else
  1134.     0,
  1135.     0,
  1136.     0,
  1137.             0,
  1138.             0
  1139. #endif
  1140.         },{
  1141. #ifdef _FAT_HXCOLOR
  1142.             ROW_FN(BGR32 ,RGB24 ,SHRINK),
  1143.             ROW_FN(BGR32 ,RGB24 ,COPY),
  1144.             ROW_FN(BGR32 ,RGB24 ,STRETCH),
  1145.             ROW_FN(BGR32 ,RGB24 ,STRETCH2X),
  1146.             ROW_FN(BGR32 ,RGB24 ,STRETCH2XPLUS)
  1147. #else
  1148.     0,
  1149.     0,
  1150.     0,
  1151.             0,
  1152.             0
  1153. #endif
  1154.         },{
  1155. #ifdef _FAT_HXCOLOR
  1156.             ROW_FN(BGR32 ,RGB565,SHRINK),
  1157.             ROW_FN(BGR32 ,RGB565,COPY),
  1158.             ROW_FN(BGR32 ,RGB565,STRETCH),
  1159.             ROW_FN(BGR32 ,RGB565,STRETCH2X),
  1160.             ROW_FN(BGR32 ,RGB565,STRETCH2XPLUS)
  1161. #else
  1162.     0,
  1163.     0,
  1164.     0,
  1165.             0,
  1166.             0
  1167. #endif
  1168.         },{
  1169. #ifdef _FAT_HXCOLOR
  1170.             ROW_FN(BGR32 ,RGB555,SHRINK),
  1171.             ROW_FN(BGR32 ,RGB555,COPY),
  1172.             ROW_FN(BGR32 ,RGB555,STRETCH),
  1173.             ROW_FN(BGR32 ,RGB555,STRETCH2X),
  1174.             ROW_FN(BGR32 ,RGB555,STRETCH2XPLUS)
  1175. #else
  1176.     0,
  1177.     0,
  1178.     0,
  1179.             0,
  1180.             0
  1181. #endif
  1182.         },{ /* rgb444 stub */
  1183.             0,
  1184.             0,
  1185.             0,
  1186.             0,
  1187.             0
  1188.         },{
  1189. #ifdef _8_BIT_SUPPORT
  1190.     ROW_FN(BGR32 ,RGB8  ,SHRINK),
  1191.             ROW_FN(BGR32 ,RGB8  ,COPY),
  1192.             ROW_FN(BGR32 ,RGB8  ,STRETCH),
  1193.             ROW_FN(BGR32 ,RGB8  ,STRETCH2X),
  1194.             ROW_FN(BGR32 ,RGB8  ,STRETCH2XPLUS)
  1195. #else
  1196.     0,
  1197.     0,
  1198.     0,
  1199.             0,
  1200.             0
  1201. #endif
  1202.         }
  1203.     },{ {
  1204.             ROW_FN(RGB24 ,RGB32 ,SHRINK),
  1205.             ROW_FN(RGB24 ,RGB32 ,COPY),
  1206.             ROW_FN(RGB24 ,RGB32 ,STRETCH),
  1207.             ROW_FN(RGB24 ,RGB32 ,STRETCH2X),
  1208.             ROW_FN(RGB24 ,RGB32 ,STRETCH2XPLUS)
  1209.         },{
  1210. #ifdef _FAT_HXCOLOR
  1211.             ROW_FN(RGB24 ,BGR32 ,SHRINK),
  1212.             ROW_FN(RGB24 ,BGR32 ,COPY),
  1213.             ROW_FN(RGB24 ,BGR32 ,STRETCH),
  1214.             ROW_FN(RGB24 ,BGR32 ,STRETCH2X),
  1215.             ROW_FN(RGB24 ,BGR32 ,STRETCH2XPLUS)
  1216. #else
  1217.     0,
  1218.     0,
  1219.     0,
  1220.     0,
  1221.     0
  1222. #endif
  1223.         },{
  1224. #ifdef _FAT_HXCOLOR
  1225.             ROW_FN(RGB24 ,RGB24 ,SHRINK),
  1226.             ROW_FN(RGB24 ,RGB24 ,COPY),
  1227.             ROW_FN(RGB24 ,RGB24 ,STRETCH),
  1228.             ROW_FN(RGB24 ,RGB24 ,STRETCH2X),
  1229.             ROW_FN(RGB24 ,RGB24 ,STRETCH2XPLUS)
  1230. #else
  1231.     0,
  1232.     0,
  1233.     0,
  1234.     0,
  1235.     0
  1236. #endif
  1237.         },{
  1238. #ifdef _FAT_HXCOLOR
  1239.             ROW_FN(RGB24 ,RGB565,SHRINK),
  1240.             ROW_FN(RGB24 ,RGB565,COPY),
  1241.             ROW_FN(RGB24 ,RGB565,STRETCH),
  1242.             ROW_FN(RGB24 ,RGB565,STRETCH2X),
  1243.             ROW_FN(RGB24 ,RGB565,STRETCH2XPLUS)
  1244. #else
  1245.     0,
  1246.     0,
  1247.     0,
  1248.     0,
  1249.     0
  1250. #endif
  1251.         },{
  1252. #ifdef _FAT_HXCOLOR
  1253.             ROW_FN(RGB24 ,RGB555,SHRINK),
  1254.             ROW_FN(RGB24 ,RGB555,COPY),
  1255.             ROW_FN(RGB24 ,RGB555,STRETCH),
  1256.             ROW_FN(RGB24 ,RGB555,STRETCH2X),
  1257.             ROW_FN(RGB24 ,RGB555,STRETCH2XPLUS)
  1258. #else
  1259.     0,
  1260.     0,
  1261.     0,
  1262.     0,
  1263.     0
  1264. #endif
  1265.         },{ /* rgb444 stub */
  1266.             0,
  1267.             0,
  1268.             0,
  1269.             0,
  1270.             0
  1271.         },{
  1272. #ifdef _8_BIT_SUPPORT
  1273.             ROW_FN(RGB24 ,RGB8  ,SHRINK),
  1274.             ROW_FN(RGB24 ,RGB8  ,COPY),
  1275.             ROW_FN(RGB24 ,RGB8  ,STRETCH),
  1276.             ROW_FN(RGB24 ,RGB8  ,STRETCH2X),
  1277.             ROW_FN(RGB24 ,RGB8  ,STRETCH2XPLUS)
  1278. #else
  1279.     0,
  1280.     0,
  1281.     0,
  1282.     0,
  1283.     0
  1284. #endif
  1285.         }
  1286.     },{ {
  1287.             ROW_FN(RGB565,RGB32 ,SHRINK),
  1288.             ROW_FN(RGB565,RGB32 ,COPY),
  1289.             ROW_FN(RGB565,RGB32 ,STRETCH),
  1290.             ROW_FN(RGB565,RGB32 ,STRETCH2X),
  1291.             ROW_FN(RGB565,RGB32 ,STRETCH2XPLUS)
  1292.         },{
  1293. #ifdef _FAT_HXCOLOR
  1294.             ROW_FN(RGB565,BGR32 ,SHRINK),
  1295.             ROW_FN(RGB565,BGR32 ,COPY),
  1296.             ROW_FN(RGB565,BGR32 ,STRETCH),
  1297.             ROW_FN(RGB565,BGR32 ,STRETCH2X),
  1298.             ROW_FN(RGB565,BGR32 ,STRETCH2XPLUS)
  1299. #else
  1300.     0,
  1301.     0,
  1302.     0,
  1303.     0,
  1304.     0
  1305. #endif
  1306.         },{
  1307. #ifdef _FAT_HXCOLOR
  1308.             ROW_FN(RGB565,RGB24 ,SHRINK),
  1309.             ROW_FN(RGB565,RGB24 ,COPY),
  1310.             ROW_FN(RGB565,RGB24 ,STRETCH),
  1311.             ROW_FN(RGB565,RGB24 ,STRETCH2X),
  1312.             ROW_FN(RGB565,RGB24 ,STRETCH2XPLUS)
  1313. #else
  1314.     0,
  1315.     0,
  1316.     0,
  1317.     0,
  1318.     0
  1319. #endif
  1320.         },{
  1321. #ifdef _FAT_HXCOLOR
  1322.             ROW_FN(RGB565,RGB565,SHRINK),
  1323.             ROW_FN(RGB565,RGB565,COPY),
  1324.             ROW_FN(RGB565,RGB565,STRETCH),
  1325.             ROW_FN(RGB565,RGB565,STRETCH2X),
  1326.             ROW_FN(RGB565,RGB565,STRETCH2XPLUS)
  1327. #else
  1328.     0,
  1329.     0,
  1330.     0,
  1331.     0,
  1332.     0
  1333. #endif
  1334.         },{
  1335. #ifdef _FAT_HXCOLOR
  1336.             ROW_FN(RGB565,RGB555,SHRINK),
  1337.             ROW_FN(RGB565,RGB555,COPY),
  1338.             ROW_FN(RGB565,RGB555,STRETCH),
  1339.             ROW_FN(RGB565,RGB555,STRETCH2X),
  1340.             ROW_FN(RGB565,RGB555,STRETCH2XPLUS)
  1341. #else
  1342.     0,
  1343.     0,
  1344.     0,
  1345.     0,
  1346.     0
  1347. #endif
  1348.         },{ /* rgb444 stub */
  1349.             0,
  1350.             0,
  1351.             0,
  1352.             0,
  1353.             0
  1354.         },{
  1355. #ifdef _8_BIT_SUPPORT
  1356.             ROW_FN(RGB565,RGB8  ,SHRINK),
  1357.             ROW_FN(RGB565,RGB8  ,COPY),
  1358.             ROW_FN(RGB565,RGB8  ,STRETCH),
  1359.             ROW_FN(RGB565,RGB8  ,STRETCH2X),
  1360.             ROW_FN(RGB565,RGB8  ,STRETCH2XPLUS)
  1361. #else
  1362.     0,
  1363.     0,
  1364.     0,
  1365.             0,
  1366.             0
  1367. #endif
  1368.         }
  1369.     },{ {
  1370.             ROW_FN(RGB555,RGB32 ,SHRINK),
  1371.             ROW_FN(RGB555,RGB32 ,COPY),
  1372.             ROW_FN(RGB555,RGB32 ,STRETCH),
  1373.             ROW_FN(RGB555,RGB32 ,STRETCH2X),
  1374.             ROW_FN(RGB555,RGB32 ,STRETCH2XPLUS)
  1375.         },{
  1376. #ifdef _FAT_HXCOLOR
  1377.             ROW_FN(RGB555,BGR32 ,SHRINK),
  1378.             ROW_FN(RGB555,BGR32 ,COPY),
  1379.             ROW_FN(RGB555,BGR32 ,STRETCH),
  1380.             ROW_FN(RGB555,BGR32 ,STRETCH2X),
  1381.             ROW_FN(RGB555,BGR32 ,STRETCH2XPLUS)
  1382. #else
  1383.     0,
  1384.     0,
  1385.     0,
  1386.             0,
  1387.             0
  1388. #endif
  1389.         },{
  1390. #ifdef _FAT_HXCOLOR
  1391.             ROW_FN(RGB555,RGB24 ,SHRINK),
  1392.             ROW_FN(RGB555,RGB24 ,COPY),
  1393.             ROW_FN(RGB555,RGB24 ,STRETCH),
  1394.             ROW_FN(RGB555,RGB24 ,STRETCH2X),
  1395.             ROW_FN(RGB555,RGB24 ,STRETCH2XPLUS)
  1396. #else
  1397.     0,
  1398.     0,
  1399.     0,
  1400.             0,
  1401.             0
  1402. #endif
  1403.         },{
  1404. #ifdef _FAT_HXCOLOR
  1405.             ROW_FN(RGB555,RGB565,SHRINK),
  1406.             ROW_FN(RGB555,RGB565,COPY),
  1407.             ROW_FN(RGB555,RGB565,STRETCH),
  1408.             ROW_FN(RGB555,RGB565,STRETCH2X),
  1409.             ROW_FN(RGB555,RGB565,STRETCH2XPLUS)
  1410. #else
  1411.     0,
  1412.     0,
  1413.     0,
  1414.             0,
  1415.             0
  1416. #endif
  1417.         },{
  1418. #ifdef _FAT_HXCOLOR
  1419.             ROW_FN(RGB555,RGB555,SHRINK),
  1420.             ROW_FN(RGB555,RGB555,COPY),
  1421.             ROW_FN(RGB555,RGB555,STRETCH),
  1422.             ROW_FN(RGB555,RGB555,STRETCH2X),
  1423.             ROW_FN(RGB555,RGB555,STRETCH2XPLUS)
  1424. #else
  1425.     0,
  1426.     0,
  1427.     0,
  1428.             0,
  1429.             0
  1430. #endif
  1431.         },{ /* rgb444 stub */
  1432.             0,
  1433.             0,
  1434.             0,
  1435.             0,
  1436.             0
  1437.         },{
  1438. #ifdef _8_BIT_SUPPORT
  1439.             ROW_FN(RGB555,RGB8  ,SHRINK),
  1440.             ROW_FN(RGB555,RGB8  ,COPY),
  1441.             ROW_FN(RGB555,RGB8  ,STRETCH),
  1442.             ROW_FN(RGB555,RGB8  ,STRETCH2X),
  1443.             ROW_FN(RGB555,RGB8  ,STRETCH2XPLUS)
  1444. #else
  1445.     0,
  1446.     0,
  1447.     0,
  1448.             0,
  1449.             0
  1450. #endif
  1451.         }
  1452.     },{ {
  1453. #ifdef _8_BIT_SUPPORT
  1454.             ROW_FN(RGB8  ,RGB32 ,SHRINK),
  1455.             ROW_FN(RGB8  ,RGB32 ,COPY),
  1456.             ROW_FN(RGB8  ,RGB32 ,STRETCH),
  1457.             ROW_FN(RGB8  ,RGB32 ,STRETCH2X),
  1458.             ROW_FN(RGB8  ,RGB32 ,STRETCH2XPLUS)
  1459. #else
  1460.     0,
  1461.     0,
  1462.     0,
  1463.             0,
  1464.             0
  1465. #endif
  1466.         },{
  1467. #ifdef _8_BIT_SUPPORT
  1468.             ROW_FN(RGB8  ,BGR32 ,SHRINK),
  1469.             ROW_FN(RGB8  ,BGR32 ,COPY),
  1470.             ROW_FN(RGB8  ,BGR32 ,STRETCH),
  1471.             ROW_FN(RGB8  ,BGR32 ,STRETCH2X),
  1472.             ROW_FN(RGB8  ,BGR32 ,STRETCH2XPLUS)
  1473. #else
  1474.     0,
  1475.     0,
  1476.     0,
  1477.             0,
  1478.             0
  1479. #endif
  1480.         },{
  1481. #ifdef _8_BIT_SUPPORT
  1482.             ROW_FN(RGB8  ,RGB24 ,SHRINK),
  1483.             ROW_FN(RGB8  ,RGB24 ,COPY),
  1484.             ROW_FN(RGB8  ,RGB24 ,STRETCH),
  1485.             ROW_FN(RGB8  ,RGB24 ,STRETCH2X),
  1486.             ROW_FN(RGB8  ,RGB24 ,STRETCH2XPLUS)
  1487. #else
  1488.     0,
  1489.     0,
  1490.     0,
  1491.             0,
  1492.             0
  1493. #endif
  1494.         },{
  1495. #ifdef _8_BIT_SUPPORT
  1496.             ROW_FN(RGB8  ,RGB565,SHRINK),
  1497.             ROW_FN(RGB8  ,RGB565,COPY),
  1498.             ROW_FN(RGB8  ,RGB565,STRETCH),
  1499.             ROW_FN(RGB8  ,RGB565,STRETCH2X),
  1500.             ROW_FN(RGB8  ,RGB565,STRETCH2XPLUS)
  1501. #else
  1502.     0,
  1503.     0,
  1504.     0,
  1505.             0,
  1506.             0
  1507. #endif
  1508.         },{
  1509. #ifdef _8_BIT_SUPPORT
  1510.             ROW_FN(RGB8  ,RGB555,SHRINK),
  1511.             ROW_FN(RGB8  ,RGB555,COPY),
  1512.             ROW_FN(RGB8  ,RGB555,STRETCH),
  1513.             ROW_FN(RGB8  ,RGB555,STRETCH2X),
  1514.             ROW_FN(RGB8  ,RGB555,STRETCH2XPLUS)
  1515. #else
  1516.     0,
  1517.     0,
  1518.     0,
  1519.             0,
  1520.             0
  1521. #endif
  1522.         },{ /* rgb444 stub */
  1523.             0,
  1524.             0,
  1525.             0,
  1526.             0,
  1527.             0
  1528.         },{
  1529. #ifdef _8_BIT_SUPPORT
  1530.             ROW_FN(RGB8  ,RGB8  ,SHRINK),
  1531.             ROW_FN(RGB8  ,RGB8  ,COPY),
  1532.             ROW_FN(RGB8  ,RGB8  ,STRETCH),
  1533.             ROW_FN(RGB8  ,RGB8  ,STRETCH2X),
  1534.             ROW_FN(RGB8  ,RGB8  ,STRETCH2XPLUS)
  1535. #else
  1536.     0,
  1537.     0,
  1538.     0,
  1539.             0,
  1540.             0
  1541. #endif
  1542.         }
  1543.     }
  1544. };
  1545. /*
  1546.  * 1.5-row scale function selection tables:
  1547.  *  [destination format][source format][row scale type]
  1548.  */
  1549. void (* Row2xFuncs [RGB_FORMATS][RGB_FORMATS][SCALE_FUNCS]) (
  1550.     unsigned char *dest_ptr_1, unsigned char *dest_ptr_12,
  1551.     unsigned char *dest_ptr_2, int dest_dx, unsigned char *src_ptr, int src_dx) =
  1552. {
  1553.     {   {
  1554.             ROW2X_FN(RGB32 ,RGB32 ,SHRINK),
  1555.             ROW2X_FN(RGB32 ,RGB32 ,COPY),
  1556.             ROW2X_FN(RGB32 ,RGB32 ,STRETCH),
  1557.             ROW2X_FN(RGB32 ,RGB32 ,STRETCH2X),
  1558.             ROW2X_FN(RGB32 ,RGB32 ,STRETCH2XPLUS)
  1559.         },{
  1560. #ifdef _FAT_HXCOLOR
  1561.             ROW2X_FN(RGB32 ,BGR32 ,SHRINK),
  1562.             ROW2X_FN(RGB32 ,BGR32 ,COPY),
  1563.             ROW2X_FN(RGB32 ,BGR32 ,STRETCH),
  1564.             ROW2X_FN(RGB32 ,BGR32 ,STRETCH2X),
  1565.             ROW2X_FN(RGB32 ,BGR32 ,STRETCH2XPLUS)
  1566. #else
  1567.     0,
  1568.     0,
  1569.     0,
  1570.             0,
  1571.             0
  1572. #endif
  1573.         },{
  1574. #ifdef _FAT_HXCOLOR
  1575.             ROW2X_FN(RGB32 ,RGB24 ,SHRINK),
  1576.             ROW2X_FN(RGB32 ,RGB24 ,COPY),
  1577.             ROW2X_FN(RGB32 ,RGB24 ,STRETCH),
  1578.             ROW2X_FN(RGB32 ,RGB24 ,STRETCH2X),
  1579.             ROW2X_FN(RGB32 ,RGB24 ,STRETCH2XPLUS)
  1580. #else
  1581.     0,
  1582.     0,
  1583.     0,
  1584.             0,
  1585.             0
  1586. #endif
  1587.         },{
  1588. #ifdef _FAT_HXCOLOR
  1589.             ROW2X_FN(RGB32 ,RGB565,SHRINK),
  1590.             ROW2X_FN(RGB32 ,RGB565,COPY),
  1591.             ROW2X_FN(RGB32 ,RGB565,STRETCH),
  1592.             ROW2X_FN(RGB32 ,RGB565,STRETCH2X),
  1593.             ROW2X_FN(RGB32 ,RGB565,STRETCH2XPLUS)
  1594. #else
  1595.     0,
  1596.     0,
  1597.     0,
  1598.             0,
  1599.             0
  1600. #endif
  1601.         },{
  1602. #ifdef _FAT_HXCOLOR
  1603.             ROW2X_FN(RGB32 ,RGB555,SHRINK),
  1604.             ROW2X_FN(RGB32 ,RGB555,COPY),
  1605.             ROW2X_FN(RGB32 ,RGB555,STRETCH),
  1606.             ROW2X_FN(RGB32 ,RGB555,STRETCH2X),
  1607.             ROW2X_FN(RGB32 ,RGB555,STRETCH2XPLUS)
  1608. #else
  1609.     0,
  1610.     0,
  1611.     0,
  1612.             0,
  1613.             0
  1614. #endif
  1615.         },{ /* rgb444 stub */
  1616.             0,
  1617.             0,
  1618.             0,
  1619.             0,
  1620.             0
  1621.         },{
  1622. #ifdef _8_BIT_SUPPORT
  1623.             ROW2X_FN(RGB32 ,RGB8  ,SHRINK),
  1624.             ROW2X_FN(RGB32 ,RGB8  ,COPY),
  1625.             ROW2X_FN(RGB32 ,RGB8  ,STRETCH),
  1626.             ROW2X_FN(RGB32 ,RGB8  ,STRETCH2X),
  1627.             ROW2X_FN(RGB32 ,RGB8  ,STRETCH2XPLUS)
  1628. #else
  1629.     0,
  1630.     0,
  1631.     0,
  1632.             0,
  1633.             0
  1634. #endif
  1635.         }
  1636.     },{ {
  1637.             ROW2X_FN(BGR32 ,RGB32 ,SHRINK),
  1638.             ROW2X_FN(BGR32 ,RGB32 ,COPY),
  1639.             ROW2X_FN(BGR32 ,RGB32 ,STRETCH),
  1640.             ROW2X_FN(BGR32 ,RGB32 ,STRETCH2X),
  1641.             ROW2X_FN(BGR32 ,RGB32 ,STRETCH2XPLUS)
  1642.         },{
  1643. #ifdef _FAT_HXCOLOR
  1644.             ROW2X_FN(BGR32 ,BGR32 ,SHRINK),
  1645.             ROW2X_FN(BGR32 ,BGR32 ,COPY),
  1646.             ROW2X_FN(BGR32 ,BGR32 ,STRETCH),
  1647.             ROW2X_FN(BGR32 ,BGR32 ,STRETCH2X),
  1648.             ROW2X_FN(BGR32 ,BGR32 ,STRETCH2XPLUS)
  1649. #else
  1650.     0,
  1651.     0,
  1652.     0,
  1653.             0,
  1654.             0
  1655. #endif
  1656.         },{
  1657. #ifdef _FAT_HXCOLOR
  1658.             ROW2X_FN(BGR32 ,RGB24 ,SHRINK),
  1659.             ROW2X_FN(BGR32 ,RGB24 ,COPY),
  1660.             ROW2X_FN(BGR32 ,RGB24 ,STRETCH),
  1661.             ROW2X_FN(BGR32 ,RGB24 ,STRETCH2X),
  1662.             ROW2X_FN(BGR32 ,RGB24 ,STRETCH2XPLUS)
  1663. #else
  1664.     0,
  1665.     0,
  1666.     0,
  1667.             0,
  1668.             0
  1669. #endif
  1670.         },{
  1671. #ifdef _FAT_HXCOLOR
  1672.             ROW2X_FN(BGR32 ,RGB565,SHRINK),
  1673.             ROW2X_FN(BGR32 ,RGB565,COPY),
  1674.             ROW2X_FN(BGR32 ,RGB565,STRETCH),
  1675.             ROW2X_FN(BGR32 ,RGB565,STRETCH2X),
  1676.             ROW2X_FN(BGR32 ,RGB565,STRETCH2XPLUS)
  1677. #else
  1678.     0,
  1679.     0,
  1680.     0,
  1681.             0,
  1682.             0
  1683. #endif
  1684.         },{
  1685. #ifdef _FAT_HXCOLOR
  1686.             ROW2X_FN(BGR32 ,RGB555,SHRINK),
  1687.             ROW2X_FN(BGR32 ,RGB555,COPY),
  1688.             ROW2X_FN(BGR32 ,RGB555,STRETCH),
  1689.             ROW2X_FN(BGR32 ,RGB555,STRETCH2X),
  1690.             ROW2X_FN(BGR32 ,RGB555,STRETCH2XPLUS)
  1691. #else
  1692.     0,
  1693.     0,
  1694.     0,
  1695.             0,
  1696.             0
  1697. #endif
  1698.         },{ /* rgb444 stub */
  1699.             0,
  1700.             0,
  1701.             0,
  1702.             0,
  1703.             0
  1704.         },{
  1705. #ifdef _8_BIT_SUPPORT
  1706.             ROW2X_FN(BGR32 ,RGB8  ,SHRINK),
  1707.             ROW2X_FN(BGR32 ,RGB8  ,COPY),
  1708.             ROW2X_FN(BGR32 ,RGB8  ,STRETCH),
  1709.             ROW2X_FN(BGR32 ,RGB8  ,STRETCH2X),
  1710.             ROW2X_FN(BGR32 ,RGB8  ,STRETCH2XPLUS)
  1711. #else
  1712.     0,
  1713.     0,
  1714.     0,
  1715.             0,
  1716.             0
  1717. #endif
  1718.         }
  1719.     },{ {
  1720.             ROW2X_FN(RGB24 ,RGB32 ,SHRINK),
  1721.             ROW2X_FN(RGB24 ,RGB32 ,COPY),
  1722.             ROW2X_FN(RGB24 ,RGB32 ,STRETCH),
  1723.             ROW2X_FN(RGB24 ,RGB32 ,STRETCH2X),
  1724.             ROW2X_FN(RGB24 ,RGB32 ,STRETCH2XPLUS)
  1725.         },{
  1726. #ifdef _FAT_HXCOLOR
  1727.             ROW2X_FN(RGB24 ,BGR32 ,SHRINK),
  1728.             ROW2X_FN(RGB24 ,BGR32 ,COPY),
  1729.             ROW2X_FN(RGB24 ,BGR32 ,STRETCH),
  1730.             ROW2X_FN(RGB24 ,BGR32 ,STRETCH2X),
  1731.             ROW2X_FN(RGB24 ,BGR32 ,STRETCH2XPLUS)
  1732. #else
  1733.     0,
  1734.     0,
  1735.     0,
  1736.             0,
  1737.             0
  1738. #endif
  1739.         },{
  1740. #ifdef _FAT_HXCOLOR
  1741.             ROW2X_FN(RGB24 ,RGB24 ,SHRINK),
  1742.             ROW2X_FN(RGB24 ,RGB24 ,COPY),
  1743.             ROW2X_FN(RGB24 ,RGB24 ,STRETCH),
  1744.             ROW2X_FN(RGB24 ,RGB24 ,STRETCH2X),
  1745.             ROW2X_FN(RGB24 ,RGB24 ,STRETCH2XPLUS)
  1746. #else
  1747.     0,
  1748.     0,
  1749.     0,
  1750.             0,
  1751.             0
  1752. #endif
  1753.         },{
  1754. #ifdef _FAT_HXCOLOR
  1755.             ROW2X_FN(RGB24 ,RGB565,SHRINK),
  1756.             ROW2X_FN(RGB24 ,RGB565,COPY),
  1757.             ROW2X_FN(RGB24 ,RGB565,STRETCH),
  1758.             ROW2X_FN(RGB24 ,RGB565,STRETCH2X),
  1759.             ROW2X_FN(RGB24 ,RGB565,STRETCH2XPLUS)
  1760. #else
  1761.     0,
  1762.     0,
  1763.     0,
  1764.             0,
  1765.             0
  1766. #endif
  1767.         },{
  1768. #ifdef _FAT_HXCOLOR
  1769.             ROW2X_FN(RGB24 ,RGB555,SHRINK),
  1770.             ROW2X_FN(RGB24 ,RGB555,COPY),
  1771.             ROW2X_FN(RGB24 ,RGB555,STRETCH),
  1772.             ROW2X_FN(RGB24 ,RGB555,STRETCH2X),
  1773.             ROW2X_FN(RGB24 ,RGB555,STRETCH2XPLUS)
  1774. #else
  1775.     0,
  1776.     0,
  1777.     0,
  1778.             0,
  1779.             0
  1780. #endif
  1781.         },{ /* rgb444 stub */
  1782.             0,
  1783.             0,
  1784.             0,
  1785.             0,
  1786.             0
  1787.         },{
  1788. #ifdef _8_BIT_SUPPORT
  1789.             ROW2X_FN(RGB24 ,RGB8  ,SHRINK),
  1790.             ROW2X_FN(RGB24 ,RGB8  ,COPY),
  1791.             ROW2X_FN(RGB24 ,RGB8  ,STRETCH),
  1792.             ROW2X_FN(RGB24 ,RGB8  ,STRETCH2X),
  1793.             ROW2X_FN(RGB24 ,RGB8  ,STRETCH2XPLUS)
  1794. #else
  1795.     0,
  1796.     0,
  1797.     0,
  1798.             0,
  1799.             0
  1800. #endif
  1801.         }
  1802.     },{ {
  1803.             ROW2X_FN(RGB565,RGB32 ,SHRINK),
  1804.             ROW2X_FN(RGB565,RGB32 ,COPY),
  1805.             ROW2X_FN(RGB565,RGB32 ,STRETCH),
  1806.             ROW2X_FN(RGB565,RGB32 ,STRETCH2X),
  1807.             ROW2X_FN(RGB565,RGB32 ,STRETCH2XPLUS)
  1808.         },{
  1809. #ifdef _FAT_HXCOLOR
  1810.             ROW2X_FN(RGB565,BGR32 ,SHRINK),
  1811.             ROW2X_FN(RGB565,BGR32 ,COPY),
  1812.             ROW2X_FN(RGB565,BGR32 ,STRETCH),
  1813.             ROW2X_FN(RGB565,BGR32 ,STRETCH2X),
  1814.             ROW2X_FN(RGB565,BGR32 ,STRETCH2XPLUS)
  1815. #else
  1816.     0,
  1817.     0,
  1818.     0,
  1819.             0,
  1820.             0
  1821. #endif
  1822.         },{
  1823. #ifdef _FAT_HXCOLOR
  1824.             ROW2X_FN(RGB565,RGB24 ,SHRINK),
  1825.             ROW2X_FN(RGB565,RGB24 ,COPY),
  1826.             ROW2X_FN(RGB565,RGB24 ,STRETCH),
  1827.             ROW2X_FN(RGB565,RGB24 ,STRETCH2X),
  1828.             ROW2X_FN(RGB565,RGB24 ,STRETCH2XPLUS)
  1829. #else
  1830.     0,
  1831.     0,
  1832.     0,
  1833.             0,
  1834.             0
  1835. #endif
  1836.         },{
  1837. #ifdef _FAT_HXCOLOR
  1838.             ROW2X_FN(RGB565,RGB565,SHRINK),
  1839.             ROW2X_FN(RGB565,RGB565,COPY),
  1840.             ROW2X_FN(RGB565,RGB565,STRETCH),
  1841.             ROW2X_FN(RGB565,RGB565,STRETCH2X),
  1842.             ROW2X_FN(RGB565,RGB565,STRETCH2XPLUS)
  1843. #else
  1844.     0,
  1845.     0,
  1846.     0,
  1847.             0,
  1848.             0
  1849. #endif
  1850.         },{
  1851. #ifdef _FAT_HXCOLOR
  1852.             ROW2X_FN(RGB565,RGB555,SHRINK),
  1853.             ROW2X_FN(RGB565,RGB555,COPY),
  1854.             ROW2X_FN(RGB565,RGB555,STRETCH),
  1855.             ROW2X_FN(RGB565,RGB555,STRETCH2X),
  1856.             ROW2X_FN(RGB565,RGB555,STRETCH2XPLUS)
  1857. #else
  1858.     0,
  1859.     0,
  1860.     0,
  1861.             0,
  1862.             0
  1863. #endif
  1864.         },{ /* rgb444 stub */
  1865.             0,
  1866.             0,
  1867.             0,
  1868.             0,
  1869.             0
  1870.         },{
  1871. #ifdef _8_BIT_SUPPORT
  1872.             ROW2X_FN(RGB565,RGB8  ,SHRINK),
  1873.             ROW2X_FN(RGB565,RGB8  ,COPY),
  1874.             ROW2X_FN(RGB565,RGB8  ,STRETCH),
  1875.             ROW2X_FN(RGB565,RGB8  ,STRETCH2X),
  1876.             ROW2X_FN(RGB565,RGB8  ,STRETCH2XPLUS)
  1877. #else
  1878.     0,
  1879.     0,
  1880.     0,
  1881.             0,
  1882.             0
  1883. #endif
  1884.         }
  1885.     },{ {
  1886.             ROW2X_FN(RGB555,RGB32 ,SHRINK),
  1887.             ROW2X_FN(RGB555,RGB32 ,COPY),
  1888.             ROW2X_FN(RGB555,RGB32 ,STRETCH),
  1889.             ROW2X_FN(RGB555,RGB32 ,STRETCH2X),
  1890.             ROW2X_FN(RGB555,RGB32 ,STRETCH2XPLUS)
  1891.         },{
  1892. #ifdef _FAT_HXCOLOR
  1893.             ROW2X_FN(RGB555,BGR32 ,SHRINK),
  1894.             ROW2X_FN(RGB555,BGR32 ,COPY),
  1895.             ROW2X_FN(RGB555,BGR32 ,STRETCH),
  1896.             ROW2X_FN(RGB555,BGR32 ,STRETCH2X),
  1897.             ROW2X_FN(RGB555,BGR32 ,STRETCH2XPLUS)
  1898. #else
  1899.     0,
  1900.     0,
  1901.     0,
  1902.             0,
  1903.             0
  1904. #endif
  1905.         },{
  1906. #ifdef _FAT_HXCOLOR
  1907.             ROW2X_FN(RGB555,RGB24 ,SHRINK),
  1908.             ROW2X_FN(RGB555,RGB24 ,COPY),
  1909.             ROW2X_FN(RGB555,RGB24 ,STRETCH),
  1910.             ROW2X_FN(RGB555,RGB24 ,STRETCH2X),
  1911.             ROW2X_FN(RGB555,RGB24 ,STRETCH2XPLUS)
  1912. #else
  1913.     0,
  1914.     0,
  1915.     0,
  1916.             0,
  1917.             0
  1918. #endif
  1919.         },{
  1920. #ifdef _FAT_HXCOLOR
  1921.             ROW2X_FN(RGB555,RGB565,SHRINK),
  1922.             ROW2X_FN(RGB555,RGB565,COPY),
  1923.             ROW2X_FN(RGB555,RGB565,STRETCH),
  1924.             ROW2X_FN(RGB555,RGB565,STRETCH2X),
  1925.             ROW2X_FN(RGB555,RGB565,STRETCH2XPLUS)
  1926. #else
  1927.     0,
  1928.     0,
  1929.     0,
  1930.             0,
  1931.             0
  1932. #endif
  1933.         },{
  1934. #ifdef _FAT_HXCOLOR
  1935.             ROW2X_FN(RGB555,RGB555,SHRINK),
  1936.             ROW2X_FN(RGB555,RGB555,COPY),
  1937.             ROW2X_FN(RGB555,RGB555,STRETCH),
  1938.             ROW2X_FN(RGB555,RGB555,STRETCH2X),
  1939.             ROW2X_FN(RGB555,RGB555,STRETCH2XPLUS)
  1940. #else
  1941.     0,
  1942.     0,
  1943.     0,
  1944.             0,
  1945.             0
  1946. #endif
  1947.         },{ /* rgb444 stub */
  1948.             0,
  1949.             0,
  1950.             0,
  1951.             0,
  1952.             0
  1953.         },{
  1954. #ifdef _8_BIT_SUPPORT
  1955.             ROW2X_FN(RGB555,RGB8  ,SHRINK),
  1956.             ROW2X_FN(RGB555,RGB8  ,COPY),
  1957.             ROW2X_FN(RGB555,RGB8  ,STRETCH),
  1958.             ROW2X_FN(RGB555,RGB8  ,STRETCH2X),
  1959.             ROW2X_FN(RGB555,RGB8  ,STRETCH2XPLUS)
  1960. #else
  1961.     0,
  1962.     0,
  1963.     0,
  1964.             0,
  1965.             0
  1966. #endif
  1967.         }
  1968.     },{ {
  1969. #ifdef _8_BIT_SUPPORT
  1970.             ROW2X_FN(RGB8  ,RGB32 ,SHRINK),
  1971.             ROW2X_FN(RGB8  ,RGB32 ,COPY),
  1972.             ROW2X_FN(RGB8  ,RGB32 ,STRETCH),
  1973.             ROW2X_FN(RGB8  ,RGB32 ,STRETCH2X),
  1974.             ROW2X_FN(RGB8  ,RGB32 ,STRETCH2XPLUS)
  1975. #else
  1976.     0,
  1977.     0,
  1978.     0,
  1979.             0,
  1980.             0
  1981. #endif
  1982.         },{
  1983. #ifdef _8_BIT_SUPPORT
  1984.             ROW2X_FN(RGB8  ,BGR32 ,SHRINK),
  1985.             ROW2X_FN(RGB8  ,BGR32 ,COPY),
  1986.             ROW2X_FN(RGB8  ,BGR32 ,STRETCH),
  1987.             ROW2X_FN(RGB8  ,BGR32 ,STRETCH2X),
  1988.             ROW2X_FN(RGB8  ,BGR32 ,STRETCH2XPLUS)
  1989. #else
  1990.     0,
  1991.     0,
  1992.     0,
  1993.             0,
  1994.             0
  1995. #endif
  1996.         },{
  1997. #ifdef _8_BIT_SUPPORT
  1998.             ROW2X_FN(RGB8  ,RGB24 ,SHRINK),
  1999.             ROW2X_FN(RGB8  ,RGB24 ,COPY),
  2000.             ROW2X_FN(RGB8  ,RGB24 ,STRETCH),
  2001.             ROW2X_FN(RGB8  ,RGB24 ,STRETCH2X),
  2002.             ROW2X_FN(RGB8  ,RGB24 ,STRETCH2XPLUS)
  2003. #else
  2004.     0,
  2005.     0,
  2006.     0,
  2007.             0,
  2008.             0
  2009. #endif
  2010.         },{
  2011. #ifdef _8_BIT_SUPPORT
  2012.             ROW2X_FN(RGB8  ,RGB565,SHRINK),
  2013.             ROW2X_FN(RGB8  ,RGB565,COPY),
  2014.             ROW2X_FN(RGB8  ,RGB565,STRETCH),
  2015.             ROW2X_FN(RGB8  ,RGB565,STRETCH2X),
  2016.             ROW2X_FN(RGB8  ,RGB565,STRETCH2XPLUS)
  2017. #else
  2018.     0,
  2019.     0,
  2020.     0,
  2021.             0,
  2022.             0
  2023. #endif
  2024.         },{
  2025. #ifdef _8_BIT_SUPPORT
  2026.             ROW2X_FN(RGB8  ,RGB555,SHRINK),
  2027.             ROW2X_FN(RGB8  ,RGB555,COPY),
  2028.             ROW2X_FN(RGB8  ,RGB555,STRETCH),
  2029.             ROW2X_FN(RGB8  ,RGB555,STRETCH2X),
  2030.             ROW2X_FN(RGB8  ,RGB555,STRETCH2XPLUS)
  2031. #else
  2032.     0,
  2033.     0,
  2034.     0,
  2035.             0,
  2036.             0
  2037. #endif
  2038.         },{ /* rgb444 stub */
  2039.             0,
  2040.             0,
  2041.             0,
  2042.             0,
  2043.             0
  2044.         },{
  2045. #ifdef _8_BIT_SUPPORT
  2046.             ROW2X_FN(RGB8  ,RGB8  ,SHRINK),
  2047.             ROW2X_FN(RGB8  ,RGB8  ,COPY),
  2048.             ROW2X_FN(RGB8  ,RGB8  ,STRETCH),
  2049.             ROW2X_FN(RGB8  ,RGB8  ,STRETCH2X),
  2050.             ROW2X_FN(RGB8  ,RGB8  ,STRETCH2XPLUS)
  2051. #else
  2052.     0,
  2053.     0,
  2054.     0,
  2055.             0,
  2056.             0
  2057. #endif
  2058.         }
  2059.     }
  2060. };
  2061. /*** RGB image converters: *********************************/
  2062. /*
  2063.  * Image shrink converter:
  2064.  */
  2065. void IMAGE_SHRINK (
  2066.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2067.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2068.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2069.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2070.         int, unsigned char *, int))
  2071. {
  2072.     /* initialize local variables: */
  2073.     register unsigned char *d = dest_ptr;
  2074.     register unsigned char *s = src_ptr;
  2075.     register int count = dest_dy;
  2076.     register int limit = src_dy >> 1; /* -1 */
  2077.     register int step = dest_dy;
  2078.     /* check image height: */
  2079.     if (count) {
  2080.         /* the main loop: */
  2081.         do {
  2082.             /* call row-converter: */
  2083.             (* row_func) (d, dest_dx, s, src_dx);
  2084.             d += dest_pitch;
  2085.             /* inverted Bresenham stepping: */
  2086.             do {
  2087.                 /* skip rows: */
  2088.                 s += src_pitch;
  2089.             } while ((limit -= step) >= 0);
  2090.             limit += src_dy;
  2091.         } while (--count);
  2092.     }
  2093. }
  2094. /*
  2095.  * Image copy converter:
  2096.  */
  2097. void IMAGE_COPY (
  2098.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2099.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2100.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2101.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2102.         int, unsigned char *, int))
  2103. {
  2104.     /* initialize local variables: */
  2105.     register unsigned char *d = dest_ptr;
  2106.     register unsigned char *s = src_ptr;
  2107.     register int count = dest_dy;
  2108.     /* check image height: */
  2109.     if (count) {
  2110.         /* the main loop: */
  2111.         do {
  2112.             /* call row-converter: */
  2113.             (* row_func) (d, dest_dx, s, src_dx);
  2114.             /* shift pointers: */
  2115.             s += src_pitch;
  2116.             d += dest_pitch;
  2117.         } while (--count);
  2118.     }
  2119. }
  2120. /*
  2121.  * Image stretching converter:
  2122.  *  (shall not be used when dest_dy/2 >= src_dy!!!)
  2123.  */
  2124. void IMAGE_STRETCH (
  2125.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2126.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2127.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2128.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2129.         int, unsigned char *, int))
  2130. {
  2131.     /* initialize local variables: */
  2132.     register unsigned char *d = dest_ptr;
  2133.     register unsigned char *s = src_ptr;
  2134.     register int dest_dx_bytes = dest_dx * dest_bpp;
  2135.     register int count = dest_dy;
  2136.     register int limit = dest_dy >> 1; /* !!! */
  2137.     register int step = src_dy;
  2138.     /* check image height: */
  2139.     if (count) {
  2140.         goto start;
  2141.         /* the main loop: */
  2142.         do {
  2143.             /* Bresenham stepping: */
  2144.             if ((limit -= step) < 0) {
  2145.                 limit += dest_dy;
  2146.                 /* convert a new row: */
  2147.     start:      (* row_func) (d, dest_dx, s, src_dx);
  2148.                 s += src_pitch;
  2149.                 d += dest_pitch;
  2150.             } else {
  2151.                 /* replicate last row: */
  2152.                 memcpy(d, d - dest_pitch, dest_dx_bytes); /* Flawfinder: ignore */
  2153.                 d += dest_pitch;
  2154.             }
  2155.         } while (--count);
  2156.     }
  2157. }
  2158. /*
  2159.  * Image 2x-stretching converter:
  2160.  */
  2161. void IMAGE_STRETCH2X (
  2162.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2163.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2164.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2165.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2166.         int, unsigned char *, int))
  2167. {
  2168.     /* initialize local variables: */
  2169.     register unsigned char *d1 = dest_ptr;
  2170.     register unsigned char *d12 = dest_ptr + dest_pitch;
  2171.     register unsigned char *d2 = dest_ptr + dest_pitch * 2;
  2172.     register unsigned char *s = src_ptr;
  2173.     register int dest_dx_bytes = dest_dx * dest_bpp;
  2174.     register int count = src_dy;
  2175.     /* check image height: */
  2176.     if (count) {
  2177.         /* convert first row: */
  2178.         (* row_func) (d1, dest_dx, s, src_dx);
  2179.         s += src_pitch;
  2180.         /* the main loop: */
  2181.         while (--count) {
  2182.             /* process second & half-pixel rows: */
  2183.             (* row2x_func) (d1, d12, d2, dest_dx, s, src_dx);
  2184.             d1 += 2 * dest_pitch;
  2185.             d12 += 2 * dest_pitch;
  2186.             d2 += 2 * dest_pitch;
  2187.             s += src_pitch;
  2188.         }
  2189.         /* replicate the last converted row: */
  2190.         memcpy (d12, d1, dest_dx_bytes); /* Flawfinder: ignore */
  2191.     }
  2192. }
  2193. /*
  2194.  * Image 2x+ stretching converter:
  2195.  */
  2196. void IMAGE_STRETCH2XPLUS (
  2197.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2198.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2199.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2200.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2201.         int, unsigned char *, int))
  2202. {
  2203.     /* initialize local variables: */
  2204.     register unsigned char *d = dest_ptr, *d1;
  2205.     register unsigned char *s = src_ptr;
  2206.     register int dest_dx_bytes = dest_dx * dest_bpp;
  2207.     register int count = dest_dy;
  2208.     register int limit = dest_dy >> 1; /* !!! */
  2209.     register int step = src_dy << 1;   /* !!! */
  2210.     /* # of rows mapped outside source image: */
  2211.     register int remainder = (2*dest_dy - limit) / step;
  2212.     /* check destination image height: */
  2213.     if (count) {
  2214.         /* convert first row: */
  2215.         (* row_func) (d, dest_dx, s, src_dx);
  2216.         s += src_pitch;
  2217.         /* update count: */
  2218.         if (!(count -= remainder)) {
  2219.             remainder --;
  2220.             goto end;
  2221.         }
  2222.         /* main loop: */
  2223.         while (1) {
  2224.             /* replicate last converted integral row: */
  2225.             goto start;
  2226.             do {
  2227.                 /* replicate a row: */
  2228.                 memcpy(d + dest_pitch, d, dest_dx_bytes); /* Flawfinder: ignore */
  2229.                 d += dest_pitch;
  2230. start:
  2231.                 /* check if all rows are filled up: */
  2232.                 if (!(--count))
  2233.                     goto end;
  2234.             } while ((limit -= step) >= 0);
  2235.             limit += dest_dy;
  2236.             /* store current location, and scan until next integral row: */
  2237.             d1 = d;
  2238.             do {
  2239.                 /* just shift a pointer: */
  2240.                 d += dest_pitch;
  2241.                 /* check if all rows are filled up: */
  2242.                 if (!(--count))
  2243.                     goto end_2;
  2244.             } while ((limit -= step) >= 0);
  2245.             limit += dest_dy;
  2246.             /* convert next integral & previous half-pixel rows: */
  2247.             (* row2x_func) (d1, d1 + dest_pitch, d + dest_pitch, dest_dx, s, src_dx);
  2248.             d1 += dest_pitch;
  2249.             s += src_pitch;
  2250.             /* replicate half-pixel row: */
  2251.             while (d1 != d) {   /* can't use < pitch can be negative!!! */
  2252.                 /* now, we can copy it: */
  2253.                 memcpy(d1 + dest_pitch, d1, dest_dx_bytes); /* Flawfinder: ignore */
  2254.                 d1 += dest_pitch;
  2255.             }
  2256.             /* select last converted row: */
  2257.             d += dest_pitch;
  2258.         }
  2259.         /* fill space reserved for half-pixel row: */
  2260. end_2:
  2261.         while (d1 != d) {   /* can't use < pitch can be negative!!! */
  2262.             memcpy(d1 + dest_pitch, d1, dest_dx_bytes); /* Flawfinder: ignore */
  2263.             d1 += dest_pitch;
  2264.         }
  2265.         /* copy the remaining rows: */
  2266. end:
  2267.         while (remainder--) {
  2268.             memcpy(d + dest_pitch, d, dest_dx_bytes); /* Flawfinder: ignore */
  2269.             d += dest_pitch;
  2270.         }
  2271.     }
  2272. }
  2273. /*
  2274.  * Image scale functions table:
  2275.  *  [vertical scale type]
  2276.  */
  2277. void (* ImageFuncs [SCALE_FUNCS]) (
  2278.     unsigned char *dest_ptr, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  2279.     unsigned char *src_ptr, int src_dx, int src_dy, int src_pitch, int src_bpp,
  2280.     void (*row_func) (unsigned char *, int, unsigned char *, int),
  2281.     void (*row2x_func) (unsigned char *, unsigned char *, unsigned char *,
  2282.         int, unsigned char *, int)) =
  2283. {
  2284.     IMAGE_SHRINK,
  2285.     IMAGE_COPY,
  2286.     IMAGE_STRETCH,
  2287.     IMAGE_STRETCH2X,
  2288.     IMAGE_STRETCH2XPLUS
  2289. };
  2290. /*
  2291.  * Bytes per pixel (bpp) table:
  2292.  */
  2293. int bpp [RGB_FORMATS] =
  2294. {
  2295.     BPP(RGB32),
  2296.     BPP(BGR32),
  2297.     BPP(RGB24),
  2298.     BPP(RGB565),
  2299.     BPP(RGB555),
  2300.     BPP(RGB444),
  2301.     BPP(RGB8)
  2302. };
  2303. /*
  2304.  * The main RGBtoRGB converter:
  2305.  */
  2306. int RGBtoRGB (
  2307.     /* destination image parameters: */
  2308.     int dest_format, unsigned char *dest_ptr, int dest_width, int dest_height,
  2309.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  2310.     /* source image parameters: */
  2311.     int src_format, unsigned char *src_ptr, int src_width, int src_height,
  2312.     int src_pitch, int src_x, int src_y, int src_dx, int src_dy)
  2313. {
  2314.     /* pointers to low-level converters to use: */
  2315.     void (*row_proc) (unsigned char *, int, unsigned char *, int);
  2316.     void (*row2x_proc) (unsigned char *, unsigned char *, unsigned char *, int,
  2317.         unsigned char *, int);
  2318.     void (*image_proc) (unsigned char *, int, int, int, int,
  2319.         unsigned char *, int, int, int, int,
  2320.         void (*) (unsigned char *, int, unsigned char *, int),
  2321.         void (*) (unsigned char *, unsigned char *, unsigned char *, int,
  2322.             unsigned char *, int));
  2323.     /* scale types: */
  2324.     register int scale_x, scale_y;
  2325.     /* pointers and pixel depths: */
  2326.     register int dest_bpp, src_bpp;
  2327.     register unsigned char *d, *s;
  2328.     /* check arguments: */
  2329.     if (
  2330.         /* alignments: */
  2331.         ((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
  2332.         ((unsigned)src_ptr  & 3) || (src_pitch  & 3) ||
  2333.         /* image sizes: */
  2334.         dest_width <= 0 || dest_height <= 0 ||
  2335.         src_width  <= 0 || src_height  <= 0 ||
  2336.         /* rectangles: */
  2337.         dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
  2338.         src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
  2339.         /* overlaps: */
  2340.         dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
  2341.         src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
  2342.     {
  2343.         /* fail: */
  2344.         return -1;
  2345.     }
  2346.     /* get scale types: */
  2347.     GET_SCALE_TYPE(dest_dx, src_dx, scale_x);
  2348.     GET_SCALE_TYPE(dest_dy, src_dy, scale_y);
  2349.     /* select row and image converters: */
  2350.     row_proc   = RowFuncs [dest_format][src_format][scale_x];
  2351.     row2x_proc = Row2xFuncs [dest_format][src_format][scale_x];
  2352.     image_proc = ImageFuncs [scale_y];
  2353.     if (!row_proc  || !row2x_proc || !image_proc)
  2354.     {
  2355.         return 1;
  2356.     }
  2357.     /* get pixel depths: */
  2358.     dest_bpp = bpp [dest_format];
  2359.     src_bpp = bpp [src_format];
  2360.     /* check if bottom-up bitmaps: */
  2361.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  2362.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  2363.     /* get pointers: */
  2364.     d = dest_ptr + dest_x * dest_bpp + dest_y * dest_pitch;
  2365.     s = src_ptr + src_x * src_bpp + src_y * src_pitch;
  2366.     /* pass control to appropriate lower-level converters: */
  2367.     (* image_proc) (d, dest_dx, dest_dy, dest_pitch, dest_bpp,
  2368.         s, src_dx, src_dy, src_pitch, src_bpp, row_proc, row2x_proc);
  2369.     /* success: */
  2370.     return 0;
  2371. }
  2372. /*
  2373.  * Public format-conversion routines.
  2374.  * Use:
  2375.  *  int XXXXtoYYYY (unsigned char *dest_ptr, int dest_width, int dest_height,
  2376.  *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  2377.  *      unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  2378.  *      int src_x, int src_y, int src_dx, int src_dy);
  2379.  * Input:
  2380.  *  dest_ptr - pointer to a destination buffer
  2381.  *  dest_width, dest_height - width/height of the destination image (pixels)
  2382.  *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
  2383.  *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
  2384.  *  src_ptr - pointer to an input image
  2385.  *  src_width, src_height - width/height of the input image (pixels)
  2386.  *  src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
  2387.  *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
  2388.  * Returns:
  2389.  *  0 - if success; -1 if failure.
  2390.  * Note:
  2391.  *  Both source and destination buffers must be 4-bytes aligned,
  2392.  *  and their pitches (#of bytes in row) shall be multiple of 4!!!
  2393.  */
  2394. #define RGBTORGB_FUNC(df,sf)                                
  2395.     int FN(df,sf) (unsigned char *dest_ptr,                 
  2396.         int dest_width, int dest_height, int dest_pitch,    
  2397.         int dest_x, int dest_y, int dest_dx, int dest_dy,   
  2398.         unsigned char *src_ptr,                             
  2399.         int src_width, int src_height, int src_pitch,       
  2400.         int src_x, int src_y, int src_dx, int src_dy)       
  2401.     {                                                       
  2402.         return RGBtoRGB(                                    
  2403.             ID(df), dest_ptr, dest_width, dest_height,      
  2404.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,   
  2405.             ID(sf), src_ptr, src_width, src_height,         
  2406.             src_pitch, src_x, src_y, src_dx, src_dy);       
  2407.     }
  2408. RGBTORGB_FUNC(RGB32 ,RGB32 )
  2409. RGBTORGB_FUNC(RGB32 ,BGR32 )
  2410. RGBTORGB_FUNC(RGB32 ,RGB24 )
  2411. RGBTORGB_FUNC(RGB32 ,RGB565)
  2412. RGBTORGB_FUNC(RGB32 ,RGB555)
  2413. RGBTORGB_FUNC(RGB32 ,RGB8  )
  2414. RGBTORGB_FUNC(BGR32 ,RGB32 )
  2415. RGBTORGB_FUNC(BGR32 ,BGR32 )
  2416. RGBTORGB_FUNC(BGR32 ,RGB24 )
  2417. RGBTORGB_FUNC(BGR32 ,RGB565)
  2418. RGBTORGB_FUNC(BGR32 ,RGB555)
  2419. RGBTORGB_FUNC(BGR32 ,RGB8  )
  2420. RGBTORGB_FUNC(RGB24 ,RGB32 )
  2421. RGBTORGB_FUNC(RGB24 ,BGR32 )
  2422. RGBTORGB_FUNC(RGB24 ,RGB24 )
  2423. RGBTORGB_FUNC(RGB24 ,RGB565)
  2424. RGBTORGB_FUNC(RGB24 ,RGB555)
  2425. RGBTORGB_FUNC(RGB24 ,RGB8  )
  2426. RGBTORGB_FUNC(RGB565,RGB32 )
  2427. RGBTORGB_FUNC(RGB565,BGR32 )
  2428. RGBTORGB_FUNC(RGB565,RGB24 )
  2429. RGBTORGB_FUNC(RGB565,RGB565)
  2430. RGBTORGB_FUNC(RGB565,RGB555)
  2431. RGBTORGB_FUNC(RGB565,RGB8  )
  2432. RGBTORGB_FUNC(RGB555,RGB32 )
  2433. RGBTORGB_FUNC(RGB555,BGR32 )
  2434. RGBTORGB_FUNC(RGB555,RGB24 )
  2435. RGBTORGB_FUNC(RGB555,RGB565)
  2436. RGBTORGB_FUNC(RGB555,RGB555)
  2437. RGBTORGB_FUNC(RGB555,RGB8  )
  2438. RGBTORGB_FUNC(RGB8  ,RGB32 )
  2439. RGBTORGB_FUNC(RGB8  ,BGR32 )
  2440. RGBTORGB_FUNC(RGB8  ,RGB24 )
  2441. RGBTORGB_FUNC(RGB8  ,RGB565)
  2442. RGBTORGB_FUNC(RGB8  ,RGB555)
  2443. RGBTORGB_FUNC(RGB8  ,RGB8  )
  2444. /***********************************************************/
  2445. #ifdef TESTALL
  2446. /*
  2447.  * Enumerates all possible formats/sizes and checks
  2448.  * if conversion is performed correctly.
  2449.  */
  2450. /* C RunTime Header Files */
  2451. #include <stdio.h>
  2452. #include <stdlib.h>
  2453. #include <string.h>
  2454. /* image buffers: */
  2455. #define MAX_WIDTH   176
  2456. #define MAX_PITCH   ((MAX_WIDTH + 1) * 4)
  2457. #define MAX_HEIGHT  144
  2458. static char src_image [(MAX_HEIGHT+1) * MAX_PITCH]; /* Flawfinder: ignore */
  2459. static char dest_image [(MAX_HEIGHT+1) * MAX_PITCH]; /* Flawfinder: ignore */
  2460. /*
  2461.  * Unified Set/Get pixel functions:
  2462.  */
  2463. static void GetPixel (int format, unsigned char *ptr, int *pr, int *pg, int *pb)
  2464. {
  2465. #   define  GET_PIXEL(f,s,r,g,b)    
  2466.         {                           
  2467.             PIXEL(f,a);             
  2468.             LOAD(f,s,a);            
  2469.             r = GET_R(f,a);         
  2470.             g = GET_G(f,a);         
  2471.             b = GET_B(f,a);         
  2472.         }
  2473.     switch (format) {
  2474.         case ID(RGB32) : GET_PIXEL(RGB32 ,ptr,*pr,*pg,*pb); break;
  2475.         case ID(BGR32) : GET_PIXEL(BGR32 ,ptr,*pr,*pg,*pb); break;
  2476.         case ID(RGB24) : GET_PIXEL(RGB24 ,ptr,*pr,*pg,*pb); break;
  2477.         case ID(RGB565): GET_PIXEL(RGB565,ptr,*pr,*pg,*pb); break;
  2478.         case ID(RGB555): GET_PIXEL(RGB555,ptr,*pr,*pg,*pb); break;
  2479.         case ID(RGB8)  : GET_PIXEL(RGB8  ,ptr,*pr,*pg,*pb); break;
  2480.     }
  2481. }
  2482. static void SetPixel (int format, unsigned char *ptr, int r, int g, int b)
  2483. {
  2484. #   define  SET_PIXEL(f,d,r,g,b)    
  2485.         {                           
  2486.             PIXEL(f,a);             
  2487.             SET(f,a,r,g,b);         
  2488.             STORE(f,d,a);           
  2489.         }
  2490.     switch (format) {
  2491.         case ID(RGB32) : SET_PIXEL(RGB32 ,ptr,r,g,b); break;
  2492.         case ID(BGR32) : SET_PIXEL(BGR32 ,ptr,r,g,b); break;
  2493.         case ID(RGB24) : SET_PIXEL(RGB24 ,ptr,r,g,b); break;
  2494.         case ID(RGB565): SET_PIXEL(RGB565,ptr,r,g,b); break;
  2495.         case ID(RGB555): SET_PIXEL(RGB555,ptr,r,g,b); break;
  2496.         case ID(RGB8)  : SET_PIXEL(RGB8  ,ptr,r,g,b); break;
  2497.     }
  2498. }
  2499. /*
  2500.  * Test pixel value:
  2501.  */
  2502. #define TEST_R    0x80
  2503. #define TEST_G    0x80
  2504. #define TEST_B    0x80
  2505. /*
  2506.  * The test program:
  2507.  */
  2508. int main (int argc, char *argv[])
  2509. {
  2510.     int src_format, src_width, src_height;
  2511.     int dest_format, dest_width, dest_height;
  2512. /* register color in the palette: */
  2513. PAL_SET(1,TEST_R,TEST_G,TEST_B);
  2514.     PMAP_SET(1,TEST_R,TEST_G,TEST_B);
  2515.     /* the main loop: */
  2516.     for (src_format=0; src_format<RGB_FORMATS; src_format++)
  2517.     for (dest_format=1; dest_format<RGB_FORMATS; dest_format++)
  2518.     for (src_width=1; src_width<=MAX_WIDTH; src_width++)
  2519.     for (src_height=1; src_height<=MAX_HEIGHT; src_height++)
  2520.     for (dest_width=1; dest_width<=MAX_WIDTH; dest_width++)
  2521.     for (dest_height=1; dest_height<=MAX_HEIGHT; dest_height++)
  2522.     {
  2523.         register unsigned char *s, *d ;
  2524.         register int i, j;
  2525.         /* print diagnostic message: */
  2526.         printf ("testing conversion: (%d,%d,%d) -> (%d,%d,%d)... ",
  2527.             src_format, src_height, src_width, dest_format, dest_height, dest_width);
  2528.         /* clear buffers: */
  2529.         memset (src_image, 0, sizeof(src_image));
  2530.         memset (dest_image, 0, sizeof(dest_image));
  2531.         /* create source image: */
  2532.         s = src_image;
  2533.         for (i=0; i<src_height; i++) {
  2534.             for (j=0; j<src_width; j++) {
  2535.                 SetPixel(src_format, s, TEST_R, TEST_G, TEST_B);
  2536.                 s += bpp[src_format];
  2537.             }
  2538.             s += MAX_PITCH - src_width * bpp[src_format];
  2539.         }
  2540.         /* call color converter: */
  2541.         if (RGBtoRGB (dest_format, dest_image, dest_width, dest_height,
  2542.             MAX_PITCH, 0, 0, dest_width, dest_height, src_format, src_image,
  2543.             src_width, src_height, MAX_PITCH, 0, 0, src_width, src_height)) {
  2544.             printf ("RGBtoRGb error!!");
  2545.             getch();
  2546.         }
  2547.         /* test converted image: */
  2548.         d = dest_image;
  2549.         for (i=0; i<dest_height; i++) {
  2550.             int r,g,b;
  2551.             for (j=0; j<dest_width; j++) {
  2552.                 GetPixel(dest_format, d, &r, &g, &b);
  2553.                 if (r != TEST_R || g != TEST_G || b != TEST_B) {
  2554.                     printf ("{%d,%d}",i,j);
  2555.                     getch();
  2556.                 }
  2557.                 d += bpp[dest_format];
  2558.             }
  2559.             /* check pixels outside the frame !!!*/
  2560.             GetPixel(dest_format, d, &r, &g, &b);
  2561.             if (r != 0 || g != 0 || b != 0) {
  2562.                 printf ("!!!}%d,%d{",i,j);
  2563.                 getch();
  2564.             }
  2565.             d += MAX_PITCH - dest_width * bpp[dest_format];
  2566.         }
  2567.         printf ("done.n");
  2568.     }
  2569. }
  2570. #endif
  2571. /***********************************************************/
  2572. #ifdef TEST
  2573. /*
  2574.  * Test program.
  2575.  * Use:
  2576.  *  RGB2RGB <output file> <input file> [<new width> <new height>] [<new format>]
  2577.  */
  2578. /* Note: use /Zp1 (no structure alignments) to compile it !!! */
  2579. /* Windows Header Files: */
  2580. #include <windows.h>
  2581. /* C RunTime Header Files */
  2582. #include <stdio.h>
  2583. #include <stdlib.h>
  2584. #include <string.h>
  2585. /* Main program: */
  2586. int main (int argc, char *argv[])
  2587. {
  2588.     /* local variables: */
  2589.     FILE *ifp, *ofp;
  2590.     int width = 0, height = 0, format = 0;
  2591.     static struct BMPHDR {
  2592.         BITMAPFILEHEADER hdr;               /* bitmap file-header */
  2593.         BITMAPINFOHEADER bihdr;             /* bitmap info-header */
  2594.     } src_bmphdr, dest_bmphdr;
  2595.     int src_image_size, dest_image_size;
  2596.     unsigned char *src_image, *dest_image;
  2597. register int i;
  2598.     int (* func) (unsigned char *dest_ptr, int dest_width, int dest_height,
  2599.         int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  2600.         unsigned char *src_ptr, int src_width, int src_height, int src_pitch,       
  2601.         int src_x, int src_y, int src_dx, int src_dy);
  2602.     /* process program arguments: */
  2603.     if (argc < 3) {
  2604.         fprintf (stderr, "Use:ntRGB2RGB <output file> <input file> [width] [height] [format]n");
  2605. exit (EXIT_FAILURE);
  2606. }
  2607.     /* open work files: */
  2608.     if ((ofp = fopen (argv[1], "wb+")) == NULL) { /* Flawfinder: ignore */
  2609.         fprintf (stderr, "Cannot open output file.n");
  2610. exit (EXIT_FAILURE);
  2611. }
  2612. if ((ifp = fopen (argv[2], "rb")) == NULL) { /* Flawfinder: ignore */
  2613.         fprintf (stderr, "Cannot open input file.n");
  2614. exit (EXIT_FAILURE);
  2615. }
  2616.     /* retrieve optional arguments: */
  2617.     if ((argc >= 4)
  2618.      && (width = atoi(argv[3])) == 0) {
  2619.         fprintf (stderr, "Invalid image width.n");
  2620. exit (EXIT_FAILURE);
  2621.     }
  2622.     if ((argc >= 5)
  2623.      && (height = atoi(argv[4])) == 0) {
  2624.         fprintf (stderr, "Invalid image height.n");
  2625. exit (EXIT_FAILURE);
  2626.     }
  2627.     if ((argc >= 6)
  2628.      && (format = atoi(argv[5])) == 0) {
  2629.         fprintf (stderr, "Invalid image format.n");
  2630. exit (EXIT_FAILURE);
  2631.      }
  2632.     /* read input file header: */
  2633. i = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  2634.     if (fread ((void *)&src_bmphdr, 1, i, ifp) != i) {
  2635. fprintf (stderr, "Cannot read input file.n");
  2636. exit (EXIT_FAILURE);
  2637. }
  2638.     /* here we will deal with simplest BMPs only: */
  2639.     if (src_bmphdr.bihdr.biCompression != BI_RGB
  2640.      || src_bmphdr.hdr.bfOffBits != i) {
  2641.         fprintf (stderr, "Sorry, I cannot understand this type of bitmap.n");
  2642. exit (EXIT_FAILURE);
  2643.     }
  2644.     /* prepare output file header: */
  2645.     memcpy((void *)&dest_bmphdr, (void *)&src_bmphdr, i); /* Flawfinder: ignore */
  2646.     if (width)
  2647.         dest_bmphdr.bihdr.biWidth = width;
  2648.     if (height)
  2649.         dest_bmphdr.bihdr.biHeight = height;
  2650.     /* allocate memory for source/dest. images: */
  2651.     src_image_size = src_bmphdr.bihdr.biWidth * src_bmphdr.bihdr.biHeight * src_bmphdr.bihdr.biBitCount / 8;
  2652.     dest_image_size = dest_bmphdr.bihdr.biWidth * dest_bmphdr.bihdr.biHeight * dest_bmphdr.bihdr.biBitCount / 8;
  2653.     if ((src_image = (unsigned char *)malloc(src_image_size)) == NULL ||
  2654.         (dest_image = (unsigned char *)malloc(dest_image_size)) == NULL) {
  2655.         fprintf (stderr, "Out of memory.n");
  2656. exit (EXIT_FAILURE);
  2657.     }
  2658.     /* read input frame: */
  2659.     if (fread (src_image, 1, src_image_size, ifp) != src_image_size) {
  2660. fprintf (stderr, "Cannot read input file.n");
  2661.         goto free_exit;
  2662.     }
  2663.     /* select color converter to use: */
  2664.     switch (src_bmphdr.bihdr.biBitCount)
  2665.     {
  2666.         case 32: func = RGB32toRGB32;   break;
  2667.         case 24: func = RGB24toRGB24;   break;
  2668.         case 16: func = RGB555toRGB555; break;
  2669.         case 8:  func = RGB8toRGB8;     break;
  2670.         default:
  2671.             fprintf (stderr, "Unsupported pixel depth.n");
  2672.             goto free_exit;
  2673.     }
  2674.     /* call it: */
  2675.     if ((* func)
  2676.         (dest_image, dest_bmphdr.bihdr.biWidth, dest_bmphdr.bihdr.biHeight,
  2677.         dest_bmphdr.bihdr.biWidth * dest_bmphdr.bihdr.biBitCount / 8,
  2678.         0, 0, dest_bmphdr.bihdr.biWidth, dest_bmphdr.bihdr.biHeight,
  2679.         src_image, src_bmphdr.bihdr.biWidth, src_bmphdr.bihdr.biHeight,
  2680.         src_bmphdr.bihdr.biWidth * src_bmphdr.bihdr.biBitCount / 8,
  2681.         0, 0, src_bmphdr.bihdr.biWidth, src_bmphdr.bihdr.biHeight))
  2682.     {
  2683.         fprintf (stderr, "Format conversion error.n");
  2684.         goto free_exit;
  2685.     }
  2686.     /* save converted image: */
  2687.     if (fwrite ((void *)&dest_bmphdr, 1, i, ofp) != i
  2688.      || fwrite (dest_image, 1, dest_image_size, ofp) != dest_image_size) {
  2689.         fprintf (stderr, "Cannot save file.n");
  2690.     }
  2691. free_exit:
  2692.     /* free memory: */
  2693.     free (src_image);
  2694.     free (dest_image);
  2695. /* close files & exit: */
  2696. fclose (ifp);
  2697. fclose (ofp);
  2698.     return EXIT_SUCCESS;
  2699. }
  2700. #endif
  2701. /* rgb2rgb.c -- end of file */