Mercurial > hg > orthanc
comparison Core/Images/ImageProcessing.cpp @ 3323:a15a4b9d8c00
Added image clipping to <T> FillPolygon_ to prevent out-of-memory access
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 19 Mar 2019 09:00:34 +0100 |
parents | 59a184cbb596 |
children | 9345710bbf12 |
comparison
equal
deleted
inserted
replaced
3322:b32b7c44a223 | 3323:a15a4b9d8c00 |
---|---|
1396 int64_t value_) | 1396 int64_t value_) |
1397 { | 1397 { |
1398 typedef typename PixelTraits<TargetFormat>::PixelType TargetType; | 1398 typedef typename PixelTraits<TargetFormat>::PixelType TargetType; |
1399 | 1399 |
1400 TargetType value = PixelTraits<TargetFormat>::IntegerToPixel(value_); | 1400 TargetType value = PixelTraits<TargetFormat>::IntegerToPixel(value_); |
1401 int imageWidth = static_cast<int>(image.GetWidth()); | |
1402 int imageHeight = static_cast<int>(image.GetHeight()); | |
1401 int32_t left; | 1403 int32_t left; |
1402 int32_t right; | 1404 int32_t right; |
1403 int32_t top; | 1405 int32_t top; |
1404 int32_t bottom; | 1406 int32_t bottom; |
1405 | 1407 |
1408 // TODO: test clipping in UT (in Trello board) | |
1406 ComputePolygonExtent(left, right, top, bottom, points); | 1409 ComputePolygonExtent(left, right, top, bottom, points); |
1410 | |
1411 // clip the computed extent with the target image | |
1412 // L and R | |
1413 left = std::max(0, left); | |
1414 left = std::min(imageWidth, left); | |
1415 right = std::max(0, right); | |
1416 right = std::min(imageWidth, right); | |
1417 if (left > right) | |
1418 std::swap(left, right); | |
1419 | |
1420 // T and B | |
1421 top = std::max(0, top); | |
1422 top = std::min(imageHeight, top); | |
1423 bottom = std::max(0, bottom); | |
1424 bottom = std::min(imageHeight, bottom); | |
1425 if (top > bottom) | |
1426 std::swap(top, bottom); | |
1407 | 1427 |
1408 // from http://alienryderflex.com/polygon_fill/ | 1428 // from http://alienryderflex.com/polygon_fill/ |
1409 | 1429 |
1410 // convert all "corner" points to double only once | 1430 // convert all "corner" points to double only once |
1411 std::vector<double> cpx; | 1431 std::vector<double> cpx; |
1458 } | 1478 } |
1459 } | 1479 } |
1460 | 1480 |
1461 TargetType* row = reinterpret_cast<TargetType*>(image.GetRow(pixelY)); | 1481 TargetType* row = reinterpret_cast<TargetType*>(image.GetRow(pixelY)); |
1462 // Fill the pixels between node pairs. | 1482 // Fill the pixels between node pairs. |
1463 for (i=0; i<nodes; i+=2) | 1483 for (i = 0; i < nodes; i += 2) |
1464 { | 1484 { |
1465 if (nodeX[i] >= right) | 1485 if (nodeX[i] >= right) |
1466 break; | 1486 break; |
1467 | 1487 |
1468 if (nodeX[i+1] >= left) | 1488 if (nodeX[i + 1] >= left) |
1469 { | 1489 { |
1470 if (nodeX[i]< left) | 1490 if (nodeX[i] < left) |
1471 { | 1491 { |
1472 nodeX[i] = left; | 1492 nodeX[i] = left; |
1473 } | 1493 } |
1474 | 1494 |
1475 if (nodeX[i+1] > right) | 1495 if (nodeX[i + 1] > right) |
1476 { | 1496 { |
1477 nodeX[i+1] = right; | 1497 nodeX[i + 1] = right; |
1478 } | 1498 } |
1479 | 1499 |
1480 for (pixelX = nodeX[i]; pixelX <= nodeX[i+1]; pixelX++) | 1500 for (pixelX = nodeX[i]; pixelX <= nodeX[i + 1]; pixelX++) |
1481 { | 1501 { |
1482 *(row + pixelX) = value; | 1502 *(row + pixelX) = value; |
1483 } | 1503 } |
1484 } | 1504 } |
1485 } | 1505 } |