Mercurial > love-experiments
annotate src/modules/image/ImageData.cpp @ 1158:82df76da9b39
Fix issue #514: Redundant if-clause in ImageData::paste
| author | vrld <vrld@vrld.org> |
|---|---|
| date | Fri, 23 Nov 2012 09:12:07 +0100 |
| parents | 86a44f2bc38f |
| children | acc815b40a4d b7f097053d74 |
| rev | line source |
|---|---|
| 1096 | 1 /** |
| 2 * Copyright (c) 2006-2012 LOVE Development Team | |
| 3 * | |
| 4 * This software is provided 'as-is', without any express or implied | |
| 5 * warranty. In no event will the authors be held liable for any damages | |
| 6 * arising from the use of this software. | |
| 7 * | |
| 8 * Permission is granted to anyone to use this software for any purpose, | |
| 9 * including commercial applications, and to alter it and redistribute it | |
| 10 * freely, subject to the following restrictions: | |
| 11 * | |
| 12 * 1. The origin of this software must not be misrepresented; you must not | |
| 13 * claim that you wrote the original software. If you use this software | |
| 14 * in a product, an acknowledgment in the product documentation would be | |
| 15 * appreciated but is not required. | |
| 16 * 2. Altered source versions must be plainly marked as such, and must not be | |
| 17 * misrepresented as being the original software. | |
| 18 * 3. This notice may not be removed or altered from any source distribution. | |
| 19 **/ | |
| 20 | |
| 21 #include "ImageData.h" | |
| 22 | |
| 23 using love::thread::Lock; | |
| 24 | |
| 25 namespace love | |
| 26 { | |
| 27 namespace image | |
| 28 { | |
| 29 | |
| 30 void *ImageData::getData() const | |
| 31 { | |
| 32 return data; | |
| 33 } | |
| 34 | |
| 35 int ImageData::getSize() const | |
| 36 { | |
| 37 return getWidth()*getHeight()*sizeof(pixel); | |
| 38 } | |
| 39 | |
| 40 int ImageData::getWidth() const | |
| 41 { | |
| 42 return width; | |
| 43 } | |
| 44 | |
| 45 int ImageData::getHeight() const | |
| 46 { | |
| 47 return height; | |
| 48 } | |
| 49 | |
| 50 bool ImageData::inside(int x, int y) const | |
| 51 { | |
| 52 return x >= 0 && x < getWidth() && y >= 0 && y < getHeight(); | |
| 53 } | |
| 54 | |
| 55 void ImageData::setPixel(int x, int y, pixel c) | |
| 56 { | |
| 57 if (!inside(x, y)) | |
| 58 throw love::Exception("Attempt to set out-of-range pixel!"); | |
| 59 | |
| 60 Lock lock(mutex); | |
| 61 | |
| 62 pixel *pixels = (pixel *)getData(); | |
| 63 pixels[y*getWidth()+x] = c; | |
| 64 } | |
| 65 | |
| 66 pixel ImageData::getPixel(int x, int y) | |
| 67 { | |
| 68 if (!inside(x, y)) | |
| 69 throw love::Exception("Attempt to get out-of-range pixel!"); | |
| 70 | |
| 71 Lock lock(mutex); | |
| 72 | |
| 73 pixel *pixels = (pixel *)getData(); | |
| 74 return pixels[y*getWidth()+x]; | |
| 75 } | |
| 76 | |
| 77 void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, int sh) | |
| 78 { | |
| 79 Lock lock2(src->mutex); | |
| 80 Lock lock1(mutex); | |
| 81 | |
| 82 pixel *s = (pixel *)src->getData(); | |
| 83 pixel *d = (pixel *)getData(); | |
| 84 | |
| 85 // Check bounds; if the data ends up completely out of bounds, get out early. | |
| 86 if (sx >= src->getWidth() || sx + sw < 0 || sy >= src->getHeight() || sy + sh < 0 | |
| 87 || dx >= getWidth() || dx + sw < 0 || dy >= getHeight() || dy + sh < 0) | |
| 88 return; | |
| 89 | |
| 90 // Normalize values to the inside of both images. | |
| 91 if (dx < 0) | |
| 92 { | |
| 93 sw += dx; | |
| 94 sx -= dx; | |
| 95 dx = 0; | |
| 96 } | |
| 97 if (dy < 0) | |
| 98 { | |
| 99 sh += dy; | |
| 100 sy -= dy; | |
| 101 dy = 0; | |
| 102 } | |
| 103 if (sx < 0) | |
| 104 { | |
| 105 sw += sx; | |
| 106 dx -= sx; | |
| 107 sx = 0; | |
| 108 } | |
| 109 if (sy < 0) | |
| 110 { | |
| 111 sh += sy; | |
| 112 dy -= sy; | |
| 113 sy = 0; | |
| 114 } | |
| 115 if (dx + sw > getWidth()) | |
| 116 { | |
| 117 sw = getWidth() - dx; | |
| 118 } | |
| 119 if (dy + sh > getHeight()) | |
| 120 { | |
| 121 sh = getHeight() - dy; | |
| 122 } | |
| 123 if (sx + sw > src->getWidth()) | |
| 124 { | |
| 125 sw = src->getWidth() - sx; | |
| 126 } | |
| 127 if (sy + sh > src->getHeight()) | |
| 128 { | |
| 129 sh = src->getHeight() - sy; | |
| 130 } | |
| 131 | |
| 132 // If the dimensions match up, copy the entire memory stream in one go | |
| 133 if (sw == getWidth() && getWidth() == src->getWidth() | |
| 134 && sh == getHeight() && getHeight() == src->getHeight()) | |
| 135 memcpy(d, s, sizeof(pixel) * sw * sh); | |
|
1158
82df76da9b39
Fix issue #514: Redundant if-clause in ImageData::paste
vrld <vrld@vrld.org>
parents:
1096
diff
changeset
|
136 else if (sw > 0) // Otherwise, copy each row individually |
| 1096 | 137 { |
| 138 for (int i = 0; i < sh; i++) | |
| 139 { | |
| 140 memcpy(d + dx + (i + dy) * getWidth(), s + sx + (i + sy) * src->getWidth(), sizeof(pixel) * sw); | |
| 141 } | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 bool ImageData::getConstant(const char *in, ImageData::Format &out) | |
| 146 { | |
| 147 return formats.find(in, out); | |
| 148 } | |
| 149 | |
| 150 bool ImageData::getConstant(ImageData::Format in, const char *&out) | |
| 151 { | |
| 152 return formats.find(in, out); | |
| 153 } | |
| 154 | |
| 155 StringMap<ImageData::Format, ImageData::FORMAT_MAX_ENUM>::Entry ImageData::formatEntries[] = | |
| 156 { | |
| 157 {"tga", ImageData::FORMAT_TGA}, | |
| 158 {"bmp", ImageData::FORMAT_BMP}, | |
| 159 {"gif", ImageData::FORMAT_GIF}, | |
| 160 {"jpg", ImageData::FORMAT_JPG}, | |
| 161 {"png", ImageData::FORMAT_PNG}, | |
| 162 }; | |
| 163 | |
| 164 StringMap<ImageData::Format, ImageData::FORMAT_MAX_ENUM> ImageData::formats(ImageData::formatEntries, sizeof(ImageData::formatEntries)); | |
| 165 | |
| 166 } // image | |
| 167 } // love |
