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 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 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