1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer/**************************************************************************
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman *
36c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
46c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * All Rights Reserved.
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner *
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * Permission is hereby granted, free of charge, to any person obtaining a
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman * copy of this software and associated documentation files (the
86c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * "Software"), to deal in the Software without restriction, including
96c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * without limitation the rights to use, copy, modify, merge, publish,
106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * distribute, sub license, and/or sell copies of the Software, and to
116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * permit persons to whom the Software is furnished to do so, subject to
1263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman * the following conditions:
139a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson *
149a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson * The above copyright notice and this permission notice (including the
159a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson * next paragraph) shall be included in all copies or substantial portions
169a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson * of the Software.
176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke *
186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
238b67f774e9c38b7718b2b300b628388f966df4e0Chandler Carruth * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
246c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
256c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke *
266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke **************************************************************************/
276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke/**
296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke * Rectangle-related helper functions.
306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke */
316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
336c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "util/u_format.h"
346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "util/u_rect.h"
356c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "util/u_pack_color.h"
36620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke
37620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke
38620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke/**
39620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke * Copy 2D rect from one place to another.
40620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke * Position and sizes are in pixels.
41620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke * src_stride may be negative to do vertical flip of pixels from source.
42620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke */
43620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaekevoid
44620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaekeutil_copy_rect(ubyte * dst,
45620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               enum pipe_format format,
466c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke               unsigned dst_stride,
47757c1f9d87b516a1e3bc4cd678245b207ae9c559Brian Gaeke               unsigned dst_x,
486c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke               unsigned dst_y,
499a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               unsigned width,
509a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               unsigned height,
519a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               const ubyte * src,
529a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               int src_stride,
539a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               unsigned src_x,
549a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson               unsigned src_y)
559a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson{
569a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   unsigned i;
579a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
589a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blocksize = util_format_get_blocksize(format);
599a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blockwidth = util_format_get_blockwidth(format);
609a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blockheight = util_format_get_blockheight(format);
619a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson
629a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   assert(blocksize > 0);
639a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   assert(blockwidth > 0);
646c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   assert(blockheight > 0);
659a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson
666c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst_x /= blockwidth;
676c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst_y /= blockheight;
686c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   width = (width + blockwidth - 1)/blockwidth;
696c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   height = (height + blockheight - 1)/blockheight;
706c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   src_x /= blockwidth;
716c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   src_y /= blockheight;
726c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
736c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst += dst_x * blocksize;
746c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   src += src_x * blocksize;
756c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst += dst_y * dst_stride;
766c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   src += src_y * src_stride_pos;
776c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   width *= blocksize;
786c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
79fe4591bfc2b147c10d6a7b1a5af56454fb78daceStephen Wilson   if (width == dst_stride && width == src_stride)
80314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson      memcpy(dst, src, height * width);
816c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   else {
829a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson      for (i = 0; i < height; i++) {
839a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson         memcpy(dst, src, width);
846c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         dst += dst_stride;
856c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         src += src_stride;
86620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke      }
87620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke   }
88e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke}
899a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson
90620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaekevoid
91620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaekeutil_fill_rect(ubyte * dst,
92620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               enum pipe_format format,
93620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               unsigned dst_stride,
94620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               unsigned dst_x,
95620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               unsigned dst_y,
96620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               unsigned width,
97620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               unsigned height,
98620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke               union util_color *uc)
99620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke{
100620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke   const struct util_format_description *desc = util_format_description(format);
101620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke   unsigned i, j;
102620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke   unsigned width_size;
1039a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blocksize = desc->block.bits / 8;
1049a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blockwidth = desc->block.width;
1059a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   int blockheight = desc->block.height;
1069a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson
1079a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson   assert(blocksize > 0);
108e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke   assert(blockwidth > 0);
109620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke   assert(blockheight > 0);
1106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
1116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst_x /= blockwidth;
1126c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst_y /= blockheight;
1136c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   width = (width + blockwidth - 1)/blockwidth;
1146c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   height = (height + blockheight - 1)/blockheight;
1156c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
1166c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst += dst_x * blocksize;
1176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   dst += dst_y * dst_stride;
1186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   width_size = width * blocksize;
1196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke
1206c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   switch (blocksize) {
1215af8f421b6412e52530608097e39d2602195629fDan Gohman   case 1:
1225af8f421b6412e52530608097e39d2602195629fDan Gohman      if(dst_stride == width_size)
1235af8f421b6412e52530608097e39d2602195629fDan Gohman         memset(dst, uc->ub, height * width_size);
1245af8f421b6412e52530608097e39d2602195629fDan Gohman      else {
1255af8f421b6412e52530608097e39d2602195629fDan Gohman         for (i = 0; i < height; i++) {
1265af8f421b6412e52530608097e39d2602195629fDan Gohman            memset(dst, uc->ub, width_size);
1276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke            dst += dst_stride;
1286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         }
12917ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      }
13017ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      break;
13117ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck   case 2:
13217ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      for (i = 0; i < height; i++) {
13317ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         uint16_t *row = (uint16_t *)dst;
13417ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         for (j = 0; j < width; j++)
13517ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck            *row++ = uc->us;
13617ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         dst += dst_stride;
13717ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      }
13817ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      break;
13917ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck   case 4:
14017ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck      for (i = 0; i < height; i++) {
14117ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         uint32_t *row = (uint32_t *)dst;
14217ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         for (j = 0; j < width; j++)
14317ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck            *row++ = uc->ui;
14417ffc5271802e68408bc18a390d8f5dc22c8771aWesley Peck         dst += dst_stride;
1456c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke      }
1466c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke      break;
1476c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   case 8:
1486c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   case 12:
1496c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   case 16:
1506c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   case 24:
1516c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke   case 32:
1526c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke      for (i = 0; i < height; i++) {
1536c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         ubyte *row = dst;
1546c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         for (j = 0; j < width; j++) {
1559a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson            memcpy(row, uc, blocksize);
1566c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke            row += blocksize;
1576c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         }
1586c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke         dst += dst_stride;
1596c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke      }
160e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming      break;
1615af8f421b6412e52530608097e39d2602195629fDan Gohman   default:
162e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming      assert(0);
163e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming      break;
164e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming   }
165e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming}
166e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming