1
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29
30 // Interface header.
31 #include "nativedrawing.h"
32
33 // appleseed.foundation headers.
34 #include "foundation/image/pixel.h"
35 #include "foundation/image/tile.h"
36
37 // Standard headers.
38 #include <cassert>
39 #include <cstring>
40
41 using namespace std;
42
43 namespace foundation
44 {
45
46 //
47 // NativeDrawing class implementation.
48 //
49
clear(uint8 * dest,const size_t dest_width,const size_t dest_height,const size_t dest_stride,const uint8 * pixel,const size_t pixel_size)50 void NativeDrawing::clear(
51 uint8* dest,
52 const size_t dest_width,
53 const size_t dest_height,
54 const size_t dest_stride,
55 const uint8* pixel,
56 const size_t pixel_size)
57 {
58 assert(dest);
59 assert(pixel);
60 assert(pixel_size > 0);
61
62 // Clear the first row.
63 for (size_t i = 0; i < dest_width; ++i)
64 memcpy(&dest[i * pixel_size], pixel, pixel_size);
65
66 // Clear the remaining rows.
67 for (size_t i = 1; i < dest_height; ++i)
68 memcpy(&dest[i * dest_stride], dest, pixel_size * dest_width);
69 }
70
draw_hline(uint8 * dest,const int span,const uint8 * pixel,const size_t pixel_size)71 void NativeDrawing::draw_hline(
72 uint8* dest,
73 const int span,
74 const uint8* pixel,
75 const size_t pixel_size)
76 {
77 assert(dest);
78 assert(pixel);
79 assert(pixel_size > 0);
80
81 const uint8* end = dest + span * pixel_size;
82 const int step = span < 0 ? -static_cast<int>(pixel_size) : static_cast<int>(pixel_size);
83
84 while (dest != end)
85 {
86 memcpy(dest, pixel, pixel_size);
87 dest += step;
88 }
89 }
90
draw_vline(uint8 * dest,const size_t dest_stride,const int span,const uint8 * pixel,const size_t pixel_size)91 void NativeDrawing::draw_vline(
92 uint8* dest,
93 const size_t dest_stride,
94 const int span,
95 const uint8* pixel,
96 const size_t pixel_size)
97 {
98 assert(dest);
99 assert(pixel);
100 assert(pixel_size > 0);
101
102 const uint8* end = dest + span * dest_stride;
103 const int step = span < 0 ? -static_cast<int>(dest_stride) : static_cast<int>(dest_stride);
104
105 while (dest != end)
106 {
107 memcpy(dest, pixel, pixel_size);
108 dest += step;
109 }
110 }
111
blit(uint8 * dest,const size_t dest_stride,const Tile & tile)112 void NativeDrawing::blit(
113 uint8* dest,
114 const size_t dest_stride,
115 const Tile& tile)
116 {
117 assert(dest);
118
119 // Retrieve tile size.
120 const size_t tile_width = tile.get_width();
121 const size_t tile_height = tile.get_height();
122
123 // Compute the size of one row of the tile.
124 const size_t pixel_size =
125 tile.get_channel_count() * Pixel::size(tile.get_pixel_format());
126 const size_t src_row_size = tile_width * pixel_size;
127
128 // Retrieve pointer to the pixel data of the tile.
129 const uint8* src = tile.pixel(0, 0);
130
131 // Copy the tile into the image.
132 for (size_t i = 0; i < tile_height; ++i)
133 {
134 memcpy(
135 &dest[i * dest_stride],
136 &src[i * src_row_size],
137 src_row_size);
138 }
139 }
140
141 } // namespace foundation
142