Home | History | Annotate | Download | only in util
      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