rgb2rgb.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:98k
源码类别:

Symbian

开发平台:

Visual C++

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