1 /**************************************************************************
2  *
3  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * Rectangle-related helper functions.
30  */
31 
32 
33 #include "util/u_format.h"
34 #include "util/u_rect.h"
35 #include "util/u_pack_color.h"
36 
37 
38 /**
39  * Copy 2D rect from one place to another.
40  * Position and sizes are in pixels.
41  * src_stride may be negative to do vertical flip of pixels from source.
42  */
43 void
util_copy_rect(ubyte * dst,enum pipe_format format,unsigned dst_stride,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,const ubyte * src,int src_stride,unsigned src_x,unsigned src_y)44 util_copy_rect(ubyte * dst,
45                enum pipe_format format,
46                unsigned dst_stride,
47                unsigned dst_x,
48                unsigned dst_y,
49                unsigned width,
50                unsigned height,
51                const ubyte * src,
52                int src_stride,
53                unsigned src_x,
54                unsigned src_y)
55 {
56    unsigned i;
57    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
58    int blocksize = util_format_get_blocksize(format);
59    int blockwidth = util_format_get_blockwidth(format);
60    int blockheight = util_format_get_blockheight(format);
61 
62    assert(blocksize > 0);
63    assert(blockwidth > 0);
64    assert(blockheight > 0);
65 
66    dst_x /= blockwidth;
67    dst_y /= blockheight;
68    width = (width + blockwidth - 1)/blockwidth;
69    height = (height + blockheight - 1)/blockheight;
70    src_x /= blockwidth;
71    src_y /= blockheight;
72 
73    dst += dst_x * blocksize;
74    src += src_x * blocksize;
75    dst += dst_y * dst_stride;
76    src += src_y * src_stride_pos;
77    width *= blocksize;
78 
79    if (width == dst_stride && width == src_stride)
80       memcpy(dst, src, height * width);
81    else {
82       for (i = 0; i < height; i++) {
83          memcpy(dst, src, width);
84          dst += dst_stride;
85          src += src_stride;
86       }
87    }
88 }
89 
90 void
util_fill_rect(ubyte * dst,enum pipe_format format,unsigned dst_stride,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,union util_color * uc)91 util_fill_rect(ubyte * dst,
92                enum pipe_format format,
93                unsigned dst_stride,
94                unsigned dst_x,
95                unsigned dst_y,
96                unsigned width,
97                unsigned height,
98                union util_color *uc)
99 {
100    const struct util_format_description *desc = util_format_description(format);
101    unsigned i, j;
102    unsigned width_size;
103    int blocksize = desc->block.bits / 8;
104    int blockwidth = desc->block.width;
105    int blockheight = desc->block.height;
106 
107    assert(blocksize > 0);
108    assert(blockwidth > 0);
109    assert(blockheight > 0);
110 
111    dst_x /= blockwidth;
112    dst_y /= blockheight;
113    width = (width + blockwidth - 1)/blockwidth;
114    height = (height + blockheight - 1)/blockheight;
115 
116    dst += dst_x * blocksize;
117    dst += dst_y * dst_stride;
118    width_size = width * blocksize;
119 
120    switch (blocksize) {
121    case 1:
122       if(dst_stride == width_size)
123          memset(dst, uc->ub, height * width_size);
124       else {
125          for (i = 0; i < height; i++) {
126             memset(dst, uc->ub, width_size);
127             dst += dst_stride;
128          }
129       }
130       break;
131    case 2:
132       for (i = 0; i < height; i++) {
133          uint16_t *row = (uint16_t *)dst;
134          for (j = 0; j < width; j++)
135             *row++ = uc->us;
136          dst += dst_stride;
137       }
138       break;
139    case 4:
140       for (i = 0; i < height; i++) {
141          uint32_t *row = (uint32_t *)dst;
142          for (j = 0; j < width; j++)
143             *row++ = uc->ui;
144          dst += dst_stride;
145       }
146       break;
147    case 8:
148    case 12:
149    case 16:
150    case 24:
151    case 32:
152       for (i = 0; i < height; i++) {
153          ubyte *row = dst;
154          for (j = 0; j < width; j++) {
155             memcpy(row, uc, blocksize);
156             row += blocksize;
157          }
158          dst += dst_stride;
159       }
160       break;
161    default:
162       assert(0);
163       break;
164    }
165 }
166