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