1e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**************************************************************************
2e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
3e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * All Rights Reserved.
5e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
6e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Permission is hereby granted, free of charge, to any person obtaining a
7e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * copy of this software and associated documentation files (the
8e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * "Software"), to deal in the Software without restriction, including
9e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * without limitation the rights to use, copy, modify, merge, publish,
10e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * distribute, sub license, and/or sell copies of the Software, and to
11e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * permit persons to whom the Software is furnished to do so, subject to
12e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * the following conditions:
13e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
14e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * The above copyright notice and this permission notice (including the
15e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * next paragraph) shall be included in all copies or substantial portions
16e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * of the Software.
17e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
18e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
26e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer **************************************************************************/
27e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
28e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**
292b87174ec306673c59386102890f35907be497efBrian Paul * Rectangle-related helper functions.
30e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer */
31e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
32e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
33b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol#include "util/u_format.h"
34fe1e39afbb147deab60ecc932c24f921b46f1364Brian Paul#include "util/u_rect.h"
35c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger#include "util/u_pack_color.h"
36e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
37e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
38e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**
39e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Copy 2D rect from one place to another.
40e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Position and sizes are in pixels.
41c3e846af30a3791a4bf80ac53c2e2d3cd6882d8fBrian Paul * src_stride may be negative to do vertical flip of pixels from source.
42e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer */
43e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzervoid
448604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paulutil_copy_rect(ubyte * dst,
45ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger               enum pipe_format format,
464ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_stride,
47e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned dst_x,
48e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned dst_y,
49e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned width,
50e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned height,
51e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               const ubyte * src,
524ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               int src_stride,
53e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned src_x,
54f39bae8e68bf461a424bf33112ea79aee3044615Brian Paul               unsigned src_y)
55e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer{
56e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   unsigned i;
574ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
58b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   int blocksize = util_format_get_blocksize(format);
59b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   int blockwidth = util_format_get_blockwidth(format);
60b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   int blockheight = util_format_get_blockheight(format);
61e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
62ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blocksize > 0);
63ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blockwidth > 0);
64ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blockheight > 0);
65016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul
66ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst_x /= blockwidth;
67ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst_y /= blockheight;
68ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   width = (width + blockwidth - 1)/blockwidth;
69ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   height = (height + blockheight - 1)/blockheight;
70ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   src_x /= blockwidth;
71ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   src_y /= blockheight;
724ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
73ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst += dst_x * blocksize;
74ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   src += src_x * blocksize;
754ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_y * dst_stride;
764ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   src += src_y * src_stride_pos;
77ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   width *= blocksize;
78e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
794ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   if (width == dst_stride && width == src_stride)
80e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      memcpy(dst, src, height * width);
81e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   else {
82e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      for (i = 0; i < height; i++) {
83e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer         memcpy(dst, src, width);
844ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca         dst += dst_stride;
854ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca         src += src_stride;
86e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      }
87e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   }
88e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer}
894ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
904ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonsecavoid
918604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paulutil_fill_rect(ubyte * dst,
92ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger               enum pipe_format format,
934ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_stride,
944ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_x,
954ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_y,
964ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned width,
974ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned height,
98c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger               union util_color *uc)
994ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca{
100c40c1599bb7782808a1387663d69cc9f99f4c68fKeith Whitwell   const struct util_format_description *desc = util_format_description(format);
1014ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   unsigned i, j;
1024ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   unsigned width_size;
103c40c1599bb7782808a1387663d69cc9f99f4c68fKeith Whitwell   int blocksize = desc->block.bits / 8;
104c40c1599bb7782808a1387663d69cc9f99f4c68fKeith Whitwell   int blockwidth = desc->block.width;
105c40c1599bb7782808a1387663d69cc9f99f4c68fKeith Whitwell   int blockheight = desc->block.height;
1064ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
107ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blocksize > 0);
108ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blockwidth > 0);
109ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   assert(blockheight > 0);
1104ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
111ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst_x /= blockwidth;
112ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst_y /= blockheight;
113ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   width = (width + blockwidth - 1)/blockwidth;
114ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   height = (height + blockheight - 1)/blockheight;
115c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger
116ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   dst += dst_x * blocksize;
1174ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_y * dst_stride;
118ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   width_size = width * blocksize;
119c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger
120ac400ffce62be47fc77e8d10cabcd39b92b6c627Roland Scheidegger   switch (blocksize) {
1214ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 1:
1224ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      if(dst_stride == width_size)
123c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         memset(dst, uc->ub, height * width_size);
1244ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      else {
125c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         for (i = 0; i < height; i++) {
126c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            memset(dst, uc->ub, width_size);
127c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            dst += dst_stride;
128c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         }
1294ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1304ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1314ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 2:
1324ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      for (i = 0; i < height; i++) {
133c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         uint16_t *row = (uint16_t *)dst;
134c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         for (j = 0; j < width; j++)
135c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            *row++ = uc->us;
136c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         dst += dst_stride;
1374ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1384ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1394ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 4:
1404ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      for (i = 0; i < height; i++) {
141c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         uint32_t *row = (uint32_t *)dst;
142c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         for (j = 0; j < width; j++)
143c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            *row++ = uc->ui;
144c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         dst += dst_stride;
145c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      }
146c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      break;
147c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger   case 8:
148c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger   case 12:
149c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger   case 16:
150c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger   case 24:
151c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger   case 32:
152c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      for (i = 0; i < height; i++) {
153c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         ubyte *row = dst;
154c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         for (j = 0; j < width; j++) {
155c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            memcpy(row, uc, blocksize);
156c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger            row += blocksize;
157c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         }
158c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger         dst += dst_stride;
1594ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1604ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1614ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   default:
162c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      assert(0);
163c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      break;
1644ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   }
1654ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca}
166