| 1 | static void
|
|---|
| 2 |
|
|---|
| 3 | GBM_ERR gbm_simple_scale(
|
|---|
| 4 | const byte *s, int sw, int sh,
|
|---|
| 5 | byte *d, int dw, int dh,
|
|---|
| 6 | int bpp
|
|---|
| 7 | )
|
|---|
| 8 | {
|
|---|
| 9 | int sst = ( (sw * bpp + 31) / 32 ) * 4;
|
|---|
| 10 | int dst = ( (dw * bpp + 31) / 32 ) * 4;
|
|---|
| 11 | int *xs, *ys, i;
|
|---|
| 12 | void (*scaler)(const byte *s, byte *d, int dw, int xs[]);
|
|---|
| 13 |
|
|---|
| 14 | /* Allocate memory for step arrays */
|
|---|
| 15 |
|
|---|
| 16 | if ( (xs = malloc((size_t) ((dw+1+dh+1)*sizeof(int)))) == NULL )
|
|---|
| 17 | return GBM_ERR_MEM;
|
|---|
| 18 | ys = xs + (dw+1);
|
|---|
| 19 |
|
|---|
| 20 | /* Make mapping to 0..dx from 0..sx (and same for y) */
|
|---|
| 21 |
|
|---|
| 22 | for ( i = 0; i <= dw; i++ )
|
|---|
| 23 | xs[i] = (i * sw) / dw;
|
|---|
| 24 |
|
|---|
| 25 | for ( i = 0; i <= dh; i++ )
|
|---|
| 26 | ys[i] = (i * sh) / dh;
|
|---|
| 27 |
|
|---|
| 28 | /* Compute step coefficients */
|
|---|
| 29 |
|
|---|
| 30 | for ( i = 0; i < dw; i++ )
|
|---|
| 31 | xs[i] = xs[i+1] - xs[i];
|
|---|
| 32 |
|
|---|
| 33 | for ( i = 0; i < dh; i++ )
|
|---|
| 34 | ys[i] = ys[i+1] - ys[i];
|
|---|
| 35 |
|
|---|
| 36 | /* Pick a scaling routine. Special optimisation to prevent
|
|---|
| 37 | excessive work scaling horizontally if widths are the same.
|
|---|
| 38 | Effectively reduces this code to a memcpy. */
|
|---|
| 39 |
|
|---|
| 40 | if ( dw == sw )
|
|---|
| 41 | switch ( bpp )
|
|---|
| 42 | {
|
|---|
| 43 | case 1 : scaler = fast_simple_scale_1 ; break;
|
|---|
| 44 | case 4 : scaler = fast_simple_scale_4 ; break;
|
|---|
| 45 | case 8 : scaler = fast_simple_scale_8 ; break;
|
|---|
| 46 | case 24: scaler = fast_simple_scale_24; break;
|
|---|
| 47 | }
|
|---|
| 48 | else
|
|---|
| 49 | switch ( bpp )
|
|---|
| 50 | {
|
|---|
| 51 | case 1 : scaler = simple_scale_1 ; break;
|
|---|
| 52 | case 4 : scaler = simple_scale_4 ; break;
|
|---|
| 53 | case 8 : scaler = simple_scale_8 ; break;
|
|---|
| 54 | case 24: scaler = simple_scale_24; break;
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | /* Now do guts of scaling */
|
|---|
| 58 |
|
|---|
| 59 | while ( dh-- > 0 )
|
|---|
| 60 | {
|
|---|
| 61 | (*scaler)(s, d, dw, xs);
|
|---|
| 62 | d += dst;
|
|---|
| 63 | s += (sst * *ys++);
|
|---|
| 64 | }
|
|---|
| 65 |
|
|---|
| 66 | free(xs);
|
|---|
| 67 | return GBM_ERR_OK;
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | static void expand(const byte *s, int sw, byte *d, int dw)
|
|---|
| 71 | {
|
|---|
| 72 | int n = 0, col = 0;
|
|---|
| 73 | for ( ;; )
|
|---|
| 74 | {
|
|---|
| 75 | n += dw;
|
|---|
| 76 | while ( n >= sw )
|
|---|
| 77 | {
|
|---|
| 78 | n -= sw;
|
|---|
| 79 | *d++ =
|
|---|
| 80 |
|
|---|
| 81 | col += *s++ * dw;
|
|---|
| 82 | while (
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 | for ( --
|
|---|
| 86 |
|
|---|
| 87 | int i = 0, c = 0;
|
|---|
| 88 | while ( i < sw * dw )
|
|---|
| 89 | {
|
|---|
| 90 | i += sw
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 | int i = 0, col = 0;
|
|---|
| 94 | while ( sw > 0 )
|
|---|
| 95 | {
|
|---|
| 96 | i += dx;
|
|---|
| 97 | while ( i >= sx )
|
|---|
| 98 | {
|
|---|
| 99 | i -= sx;
|
|---|
| 100 | col += *s++ * sx;
|
|---|
| 101 | *d++ = (col / dx);
|
|---|
| 102 | }
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | int i = 0, col = 0;
|
|---|
| 106 | while ( dw > 0 )
|
|---|
| 107 | {
|
|---|
| 108 |
|
|---|
| 109 |
|
|---|
| 110 | if ( i <
|
|---|
| 111 |
|
|---|
| 112 | GBM_ERR gbm_scale_8(
|
|---|
| 113 | const byte *s, int sw, int sh,
|
|---|
| 114 | byte *d, int dw, int dh
|
|---|
| 115 | )
|
|---|
| 116 | {
|
|---|
| 117 | int sst = ( (sw * 8 + 31) / 32 ) * 4;
|
|---|
| 118 | int dst = ( (dw * 8 + 31) / 32 ) * 4;
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 | int *xs, *ys, i;
|
|---|
| 126 | void (*scaler)(const byte *s, byte *d, int dw, const int xs[]);
|
|---|
| 127 |
|
|---|
| 128 | /* Allocate memory for step arrays */
|
|---|
| 129 |
|
|---|
| 130 | if ( (xs = malloc((size_t) ((dw+dh)*sizeof(int)))) == NULL )
|
|---|
| 131 | return GBM_ERR_MEM;
|
|---|
| 132 | ys = xs + dw;
|
|---|
| 133 |
|
|---|
| 134 | /* Make mapping to 0..dx-1 from 0..sx-1 (and same for y) */
|
|---|
| 135 |
|
|---|
| 136 | for ( i = 0; i < dw; i++ )
|
|---|
| 137 | xs[i] = (i * (sw-1) * 0x100) / (dw-1);
|
|---|
| 138 |
|
|---|
| 139 | for ( i = 0; i < dh; i++ )
|
|---|
| 140 | ys[i] = (i * (sh-1) * 0x100) / (dh-1);
|
|---|
| 141 |
|
|---|
| 142 | /* Compute step coefficients */
|
|---|
| 143 |
|
|---|
| 144 | for ( i = 0; i < dw; i++ )
|
|---|
| 145 | xs[i] = xs[i+1] - xs[i];
|
|---|
| 146 |
|
|---|
| 147 | for ( i = 0; i < dh; i++ )
|
|---|
| 148 | ys[i] = ys[i+1] - ys[i];
|
|---|
| 149 |
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | static void simple_scale_8(
|
|---|
| 153 | const byte *s,
|
|---|
| 154 | byte *d, int dw,
|
|---|
| 155 | int xs[]
|
|---|
| 156 | )
|
|---|
| 157 | {
|
|---|
| 158 | while ( dw-- > 0 )
|
|---|
| 159 | {
|
|---|
| 160 | *d++ = *s;
|
|---|
| 161 | s += *xs++;
|
|---|
| 162 | }
|
|---|
| 163 | }
|
|---|