Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the Scale2x project.
  3.  *
  4.  * Copyright (C) 2003, 2004 Andrea Mazzoleni
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * This file contains an example implementation of the Scale effect
  23.  * applyed to a generic bitmap.
  24.  *
  25.  * You can find an high level description of the effect at :
  26.  *
  27.  * http://scale2x.sourceforge.net/
  28.  *
  29.  * Alternatively at the previous license terms, you are allowed to use this
  30.  * code in your program with these conditions:
  31.  * - the program is not used in commercial activities.
  32.  * - the whole source code of the program is released with the binary.
  33.  * - derivative works of the program are allowed.
  34.  */
  35.  
  36. #if HAVE_CONFIG_H
  37. #include <config.h>
  38. #endif
  39.  
  40. #include "scale2x.h"
  41. #include "scale3x.h"
  42.  
  43. #if HAVE_ALLOCA_H
  44. #include <alloca.h>
  45. #endif
  46.  
  47. #include <assert.h>
  48. #include <stdlib.h>
  49.  
  50. #define SSDST(bits, num) (scale2x_uint##bits *)dst##num
  51. #define SSSRC(bits, num) (const scale2x_uint##bits *)src##num
  52.  
  53. /**
  54.  * Apply the Scale2x effect on a group of rows. Used internally.
  55.  */
  56. static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
  57. {
  58.         switch (pixel) {
  59. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  60.                 case 1 : scale2x_8_mmx(SSDST(8,0), SSDST(8,1), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  61.                 case 2 : scale2x_16_mmx(SSDST(16,0), SSDST(16,1), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  62.                 case 4 : scale2x_32_mmx(SSDST(32,0), SSDST(32,1), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  63. #else
  64.                 case 1 : scale2x_8_def(SSDST(8,0), SSDST(8,1), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  65.                 case 2 : scale2x_16_def(SSDST(16,0), SSDST(16,1), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  66.                 case 4 : scale2x_32_def(SSDST(32,0), SSDST(32,1), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  67. #endif
  68.         }
  69. }
  70.  
  71. /**
  72.  * Apply the Scale2x3 effect on a group of rows. Used internally.
  73.  */
  74. static inline void stage_scale2x3(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
  75. {
  76.         switch (pixel) {
  77. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  78.                 case 1 : scale2x3_8_mmx(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  79.                 case 2 : scale2x3_16_mmx(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  80.                 case 4 : scale2x3_32_mmx(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  81. #else
  82.                 case 1 : scale2x3_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  83.                 case 2 : scale2x3_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  84.                 case 4 : scale2x3_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  85. #endif
  86.         }
  87. }
  88.  
  89. /**
  90.  * Apply the Scale2x4 effect on a group of rows. Used internally.
  91.  */
  92. static inline void stage_scale2x4(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
  93. {
  94.         switch (pixel) {
  95. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  96.                 case 1 : scale2x4_8_mmx(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSDST(8,3), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  97.                 case 2 : scale2x4_16_mmx(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSDST(16,3), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  98.                 case 4 : scale2x4_32_mmx(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSDST(32,3), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  99. #else
  100.                 case 1 : scale2x4_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSDST(8,3), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  101.                 case 2 : scale2x4_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSDST(16,3), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  102.                 case 4 : scale2x4_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSDST(32,3), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  103. #endif
  104.         }
  105. }
  106.  
  107. /**
  108.  * Apply the Scale3x effect on a group of rows. Used internally.
  109.  */
  110. static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
  111. {
  112.         switch (pixel) {
  113.                 case 1 : scale3x_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
  114.                 case 2 : scale3x_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
  115.                 case 4 : scale3x_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
  116.         }
  117. }
  118.  
  119. /**
  120.  * Apply the Scale4x effect on a group of rows. Used internally.
  121.  */
  122. static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
  123. {
  124.         stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
  125.         stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
  126. }
  127.  
  128. #define SCDST(i) (dst+(i)*dst_slice)
  129. #define SCSRC(i) (src+(i)*src_slice)
  130. #define SCMID(i) (mid[(i)])
  131.  
  132. /**
  133.  * Apply the Scale2x effect on a bitmap.
  134.  * The destination bitmap is filled with the scaled version of the source bitmap.
  135.  * The source bitmap isn't modified.
  136.  * The destination bitmap must be manually allocated before calling the function,
  137.  * note that the resulting size is exactly 2x2 times the size of the source bitmap.
  138.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  139.  * \param dst_slice Size in bytes of a destination bitmap row.
  140.  * \param void_src Pointer at the first pixel of the source bitmap.
  141.  * \param src_slice Size in bytes of a source bitmap row.
  142.  * \param pixel Bytes per pixel of the source and destination bitmap.
  143.  * \param width Horizontal size in pixels of the source bitmap.
  144.  * \param height Vertical size in pixels of the source bitmap.
  145.  */
  146. static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  147. {
  148.         unsigned char* dst = (unsigned char*)void_dst;
  149.         const unsigned char* src = (const unsigned char*)void_src;
  150.         unsigned count;
  151.  
  152.         assert(height >= 2);
  153.  
  154.         count = height;
  155.  
  156.         stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
  157.  
  158.         dst = SCDST(2);
  159.  
  160.         count -= 2;
  161.         while (count) {
  162.                 stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
  163.  
  164.                 dst = SCDST(2);
  165.                 src = SCSRC(1);
  166.  
  167.                 --count;
  168.         }
  169.  
  170.         stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
  171.  
  172. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  173.         scale2x_mmx_emms();
  174. #endif
  175. }
  176.  
  177. /**
  178.  * Apply the Scale2x3 effect on a bitmap.
  179.  * The destination bitmap is filled with the scaled version of the source bitmap.
  180.  * The source bitmap isn't modified.
  181.  * The destination bitmap must be manually allocated before calling the function,
  182.  * note that the resulting size is exactly 2x3 times the size of the source bitmap.
  183.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  184.  * \param dst_slice Size in bytes of a destination bitmap row.
  185.  * \param void_src Pointer at the first pixel of the source bitmap.
  186.  * \param src_slice Size in bytes of a source bitmap row.
  187.  * \param pixel Bytes per pixel of the source and destination bitmap.
  188.  * \param width Horizontal size in pixels of the source bitmap.
  189.  * \param height Vertical size in pixels of the source bitmap.
  190.  */
  191. static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  192. {
  193.         unsigned char* dst = (unsigned char*)void_dst;
  194.         const unsigned char* src = (const unsigned char*)void_src;
  195.         unsigned count;
  196.  
  197.         assert(height >= 2);
  198.  
  199.         count = height;
  200.  
  201.         stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
  202.  
  203.         dst = SCDST(3);
  204.  
  205.         count -= 2;
  206.         while (count) {
  207.                 stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
  208.  
  209.                 dst = SCDST(3);
  210.                 src = SCSRC(1);
  211.  
  212.                 --count;
  213.         }
  214.  
  215.         stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
  216.  
  217. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  218.         scale2x_mmx_emms();
  219. #endif
  220. }
  221.  
  222. /**
  223.  * Apply the Scale2x4 effect on a bitmap.
  224.  * The destination bitmap is filled with the scaled version of the source bitmap.
  225.  * The source bitmap isn't modified.
  226.  * The destination bitmap must be manually allocated before calling the function,
  227.  * note that the resulting size is exactly 2x4 times the size of the source bitmap.
  228.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  229.  * \param dst_slice Size in bytes of a destination bitmap row.
  230.  * \param void_src Pointer at the first pixel of the source bitmap.
  231.  * \param src_slice Size in bytes of a source bitmap row.
  232.  * \param pixel Bytes per pixel of the source and destination bitmap.
  233.  * \param width Horizontal size in pixels of the source bitmap.
  234.  * \param height Vertical size in pixels of the source bitmap.
  235.  */
  236. static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  237. {
  238.         unsigned char* dst = (unsigned char*)void_dst;
  239.         const unsigned char* src = (const unsigned char*)void_src;
  240.         unsigned count;
  241.  
  242.         assert(height >= 2);
  243.  
  244.         count = height;
  245.  
  246.         stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
  247.  
  248.         dst = SCDST(4);
  249.  
  250.         count -= 2;
  251.         while (count) {
  252.                 stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
  253.  
  254.                 dst = SCDST(4);
  255.                 src = SCSRC(1);
  256.  
  257.                 --count;
  258.         }
  259.  
  260.         stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
  261.  
  262. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  263.         scale2x_mmx_emms();
  264. #endif
  265. }
  266.  
  267. /**
  268.  * Apply the Scale3x effect on a bitmap.
  269.  * The destination bitmap is filled with the scaled version of the source bitmap.
  270.  * The source bitmap isn't modified.
  271.  * The destination bitmap must be manually allocated before calling the function,
  272.  * note that the resulting size is exactly 3x3 times the size of the source bitmap.
  273.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  274.  * \param dst_slice Size in bytes of a destination bitmap row.
  275.  * \param void_src Pointer at the first pixel of the source bitmap.
  276.  * \param src_slice Size in bytes of a source bitmap row.
  277.  * \param pixel Bytes per pixel of the source and destination bitmap.
  278.  * \param width Horizontal size in pixels of the source bitmap.
  279.  * \param height Vertical size in pixels of the source bitmap.
  280.  */
  281. static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  282. {
  283.         unsigned char* dst = (unsigned char*)void_dst;
  284.         const unsigned char* src = (const unsigned char*)void_src;
  285.         unsigned count;
  286.  
  287.         assert(height >= 2);
  288.  
  289.         count = height;
  290.  
  291.         stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
  292.  
  293.         dst = SCDST(3);
  294.  
  295.         count -= 2;
  296.         while (count) {
  297.                 stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
  298.  
  299.                 dst = SCDST(3);
  300.                 src = SCSRC(1);
  301.  
  302.                 --count;
  303.         }
  304.  
  305.         stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
  306. }
  307.  
  308. /**
  309.  * Apply the Scale4x effect on a bitmap.
  310.  * The destination bitmap is filled with the scaled version of the source bitmap.
  311.  * The source bitmap isn't modified.
  312.  * The destination bitmap must be manually allocated before calling the function,
  313.  * note that the resulting size is exactly 4x4 times the size of the source bitmap.
  314.  * \note This function requires also a small buffer bitmap used internally to store
  315.  * intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
  316.  * and a vertical size of 6 rows. The memory of this buffer must not be allocated
  317.  * in video memory because it's also read and not only written. Generally
  318.  * a heap (malloc) or a stack (alloca) buffer is the best choice.
  319.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  320.  * \param dst_slice Size in bytes of a destination bitmap row.
  321.  * \param void_mid Pointer at the first pixel of the buffer bitmap.
  322.  * \param mid_slice Size in bytes of a buffer bitmap row.
  323.  * \param void_src Pointer at the first pixel of the source bitmap.
  324.  * \param src_slice Size in bytes of a source bitmap row.
  325.  * \param pixel Bytes per pixel of the source and destination bitmap.
  326.  * \param width Horizontal size in pixels of the source bitmap.
  327.  * \param height Vertical size in pixels of the source bitmap.
  328.  */
  329. static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  330. {
  331.         unsigned char* dst = (unsigned char*)void_dst;
  332.         const unsigned char* src = (const unsigned char*)void_src;
  333.         unsigned count;
  334.         unsigned char* mid[6];
  335.  
  336.         assert(height >= 4);
  337.  
  338.         count = height;
  339.  
  340.         /* set the 6 buffer pointers */
  341.         mid[0] = (unsigned char*)void_mid;
  342.         mid[1] = mid[0] + mid_slice;
  343.         mid[2] = mid[1] + mid_slice;
  344.         mid[3] = mid[2] + mid_slice;
  345.         mid[4] = mid[3] + mid_slice;
  346.         mid[5] = mid[4] + mid_slice;
  347.  
  348.         stage_scale2x(SCMID(-2+6), SCMID(-1+6), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
  349.         stage_scale2x(SCMID(0), SCMID(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
  350.         stage_scale2x(SCMID(2), SCMID(3), SCSRC(1), SCSRC(2), SCSRC(3), pixel, width);
  351.         stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-2+6), SCMID(-2+6), SCMID(-1+6), SCMID(0), pixel, width);
  352.  
  353.         dst = SCDST(4);
  354.  
  355.         stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-1+6), SCMID(0), SCMID(1), SCMID(2), pixel, width);
  356.  
  357.         dst = SCDST(4);
  358.  
  359.         count -= 4;
  360.         while (count) {
  361.                 unsigned char* tmp;
  362.  
  363.                 stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
  364.                 stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
  365.  
  366.                 dst = SCDST(4);
  367.                 src = SCSRC(1);
  368.  
  369.                 tmp = SCMID(0); /* shift by 2 position */
  370.                 SCMID(0) = SCMID(2);
  371.                 SCMID(2) = SCMID(4);
  372.                 SCMID(4) = tmp;
  373.                 tmp = SCMID(1);
  374.                 SCMID(1) = SCMID(3);
  375.                 SCMID(3) = SCMID(5);
  376.                 SCMID(5) = tmp;
  377.  
  378.                 --count;
  379.         }
  380.  
  381.         stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(3), pixel, width);
  382.         stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
  383.  
  384.         dst = SCDST(4);
  385.  
  386.         stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(3), SCMID(4), SCMID(5), SCMID(5), pixel, width);
  387.  
  388. #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
  389.         scale2x_mmx_emms();
  390. #endif
  391. }
  392.  
  393. /**
  394.  * Apply the Scale4x effect on a bitmap.
  395.  * The destination bitmap is filled with the scaled version of the source bitmap.
  396.  * The source bitmap isn't modified.
  397.  * The destination bitmap must be manually allocated before calling the function,
  398.  * note that the resulting size is exactly 4x4 times the size of the source bitmap.
  399.  * \note This function operates like ::scale4x_buf() but the intermediate buffer is
  400.  * automatically allocated in the stack.
  401.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  402.  * \param dst_slice Size in bytes of a destination bitmap row.
  403.  * \param void_src Pointer at the first pixel of the source bitmap.
  404.  * \param src_slice Size in bytes of a source bitmap row.
  405.  * \param pixel Bytes per pixel of the source and destination bitmap.
  406.  * \param width Horizontal size in pixels of the source bitmap.
  407.  * \param height Vertical size in pixels of the source bitmap.
  408.  */
  409. static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  410. {
  411.         unsigned mid_slice;
  412.         void* mid;
  413.  
  414.         mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
  415.  
  416.         mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
  417.  
  418. #if HAVE_ALLOCA
  419.         mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
  420.  
  421.         assert(mid != 0); /* alloca should never fails */
  422. #else
  423.         mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
  424.  
  425.         if (!mid)
  426.                 return;
  427. #endif
  428.  
  429.         scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
  430.  
  431. #if !HAVE_ALLOCA
  432.         free(mid);
  433. #endif
  434. }
  435.  
  436. /**
  437.  * Check if the scale implementation is applicable at the given arguments.
  438.  * \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
  439.  * \param pixel Bytes per pixel of the source and destination bitmap.
  440.  * \param width Horizontal size in pixels of the source bitmap.
  441.  * \param height Vertical size in pixels of the source bitmap.
  442.  * \return
  443.  *   - -1 on precondition violated.
  444.  *   - 0 on success.
  445.  */
  446. int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
  447. {
  448.         if (pixel != 1 && pixel != 2 && pixel != 4)
  449.                 return -1;
  450.  
  451.         switch (scale) {
  452.         case 202 :
  453.         case 203 :
  454.         case 204 :
  455.         case 2 :
  456.         case 303 :
  457.         case 3 :
  458.                 if (height < 2)
  459.                         return -1;
  460.                 break;
  461.         case 404 :
  462.         case 4 :
  463.                 if (height < 4)
  464.                         return -1;
  465.                 break;
  466.         default:
  467.                 return -1;
  468.         }
  469.  
  470.         if (width < 2)
  471.                 return -1;
  472.  
  473.         return 0;
  474. }
  475.  
  476. /**
  477.  * Apply the Scale effect on a bitmap.
  478.  * This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
  479.  * \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
  480.  * \param void_dst Pointer at the first pixel of the destination bitmap.
  481.  * \param dst_slice Size in bytes of a destination bitmap row.
  482.  * \param void_src Pointer at the first pixel of the source bitmap.
  483.  * \param src_slice Size in bytes of a source bitmap row.
  484.  * \param pixel Bytes per pixel of the source and destination bitmap.
  485.  * \param width Horizontal size in pixels of the source bitmap.
  486.  * \param height Vertical size in pixels of the source bitmap.
  487.  */
  488. void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
  489. {
  490.         switch (scale) {
  491.         case 202 :
  492.         case 2 :
  493.                 scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
  494.                 break;
  495.         case 203 :
  496.                 scale2x3(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
  497.                 break;
  498.         case 204 :
  499.                 scale2x4(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
  500.                 break;
  501.         case 303 :
  502.         case 3 :
  503.                 scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
  504.                 break;
  505.         case 404 :
  506.         case 4 :
  507.                 scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
  508.                 break;
  509.         }
  510. }
  511.  
  512.