227{
228 ScaledProgress progress(expansionStrategy.rect.height() * 2, progressUpdater);
229
230 QVector<quint8> distanceMapRows(expansionStrategy.rect.width() * 4 * 2);
231 QVector<quint8> deviceRows(expansionStrategy.rect.width() * expansionStrategy.sourceDevicePixelSize * 2);
232 quint8 *distanceMapRow1, *distanceMapRow2;
233 quint8 *deviceRow1, *deviceRow2;
234
235
236 distanceMapRow1 = distanceMapRows.data();
237 distanceMapRow2 = distanceMapRows.data() + expansionStrategy.rect.width() * 4;
238 deviceRow1 = deviceRows.data();
239 deviceRow2 = deviceRows.data() + expansionStrategy.rect.width() * expansionStrategy.sourceDevicePixelSize;
240
241 expansionStrategy.distanceMap->readBytes(distanceMapRow1, expansionStrategy.rect.left(),
242 expansionStrategy.rect.top(), expansionStrategy.rect.width(), 1);
243 expansionStrategy.sourceDevice->readBytes(deviceRow1, expansionStrategy.rect.left(),
244 expansionStrategy.rect.top(), expansionStrategy.rect.width(), 1);
245
246 expansionStrategy.initializePixel(reinterpret_cast<quint32*>(distanceMapRow1), deviceRow1);
247
248 {
249 quint32 *distancePixel = reinterpret_cast<quint32*>(distanceMapRow1) + 1;
250 quint8 *devicePixel = deviceRow1 + expansionStrategy.sourceDevicePixelSize;
251 for (qint32 x = 1;
x < expansionStrategy.rect.width();
252 ++
x, ++distancePixel, devicePixel += expansionStrategy.sourceDevicePixelSize) {
253
254 expansionStrategy.initializePixel(distancePixel, devicePixel);
255 if (*distancePixel == 0) {
256 continue;
257 }
258 expansionStrategy.updatePixel(
259 distancePixel, devicePixel,
260 distancePixel - 1, devicePixel - expansionStrategy.sourceDevicePixelSize,
261 expansionStrategy.orthogonalDistance
262 );
263 }
264 }
265 expansionStrategy.distanceMap->writeBytes(distanceMapRow1, expansionStrategy.rect.left(),
266 expansionStrategy.rect.top(), expansionStrategy.rect.width(), 1);
267 expansionStrategy.sourceDevice->writeBytes(deviceRow1, expansionStrategy.rect.left(),
268 expansionStrategy.rect.top(), expansionStrategy.rect.width(), 1);
269 progress.stepUp();
270
271 for (qint32 y = expansionStrategy.rect.top() + 1;
y <= expansionStrategy.rect.bottom(); ++
y) {
272 expansionStrategy.distanceMap->readBytes(distanceMapRow2, expansionStrategy.rect.left(),
273 y, expansionStrategy.rect.width(), 1);
274 expansionStrategy.sourceDevice->readBytes(deviceRow2, expansionStrategy.rect.left(),
y,
275 expansionStrategy.rect.width(), 1);
276
277 quint32 *topDistancePixel = reinterpret_cast<quint32*>(distanceMapRow1);
278 quint32 *distancePixel = reinterpret_cast<quint32*>(distanceMapRow2);
279 quint8 *topDevicePixel = deviceRow1;
280 quint8 *devicePixel = deviceRow2;
281
282 {
283 expansionStrategy.initializePixel(distancePixel, devicePixel);
284 if (*distancePixel != 0) {
285 if (expansionStrategy.rect.width() > 1) {
286 expansionStrategy.updatePixel(
287 distancePixel, devicePixel,
288 topDistancePixel, topDevicePixel,
289 topDistancePixel + 1, topDevicePixel + expansionStrategy.sourceDevicePixelSize,
290 expansionStrategy.orthogonalDistance, expansionStrategy.diagonalDistance
291 );
292 } else {
293 expansionStrategy.updatePixel(
294 distancePixel, devicePixel,
295 topDistancePixel, topDevicePixel,
296 expansionStrategy.orthogonalDistance
297 );
298 }
299 }
300 ++topDistancePixel;
301 ++distancePixel;
302 topDevicePixel += expansionStrategy.sourceDevicePixelSize;
303 devicePixel += expansionStrategy.sourceDevicePixelSize;
304 }
305
306 for (qint32 x = 1;
x < expansionStrategy.rect.width() - 1;
307 ++
x, ++topDistancePixel, ++distancePixel,
308 topDevicePixel += expansionStrategy.sourceDevicePixelSize,
309 devicePixel += expansionStrategy.sourceDevicePixelSize) {
310
311 expansionStrategy.initializePixel(distancePixel, devicePixel);
312 if (*distancePixel == 0) {
313 continue;
314 }
315 expansionStrategy.updatePixel(
316 distancePixel, devicePixel,
317 topDistancePixel - 1,topDevicePixel - expansionStrategy.sourceDevicePixelSize,
318 topDistancePixel, topDevicePixel,
319 topDistancePixel + 1, topDevicePixel + expansionStrategy.sourceDevicePixelSize,
320 distancePixel - 1, devicePixel - expansionStrategy.sourceDevicePixelSize,
321 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance,
322 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance
323 );
324 }
325
326 expansionStrategy.initializePixel(distancePixel, devicePixel);
327 if (expansionStrategy.rect.width() > 1 && *distancePixel != 0) {
328 expansionStrategy.updatePixel(
329 distancePixel, devicePixel,
330 topDistancePixel - 1, topDevicePixel - expansionStrategy.sourceDevicePixelSize,
331 distancePixel - 1, devicePixel - expansionStrategy.sourceDevicePixelSize,
332 topDistancePixel, topDevicePixel,
333 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance,
334 expansionStrategy.orthogonalDistance
335 );
336 }
337
338 expansionStrategy.distanceMap->writeBytes(distanceMapRow2, expansionStrategy.rect.left(),
339 y, expansionStrategy.rect.width(), 1);
340 expansionStrategy.sourceDevice->writeBytes(deviceRow2, expansionStrategy.rect.left(),
341 y, expansionStrategy.rect.width(), 1);
342
343 swapRowPointers(&distanceMapRow1, &distanceMapRow2, &deviceRow1, &deviceRow2);
344
345 progress.stepUp();
346 }
347
348
349
350
351
352 {
353 quint32 *distancePixel = reinterpret_cast<quint32*>(distanceMapRow1) + expansionStrategy.rect.width() - 2;
354 quint8 *devicePixel =
355 deviceRow1 + expansionStrategy.sourceDevicePixelSize * (expansionStrategy.rect.width() - 2);
356 for (qint32 x = 1;
x < expansionStrategy.rect.width();
357 ++
x, --distancePixel, devicePixel -= expansionStrategy.sourceDevicePixelSize) {
358
359 if (*distancePixel == 0) {
360 continue;
361 }
362 expansionStrategy.updatePixel(
363 distancePixel, devicePixel,
364 distancePixel + 1, devicePixel + expansionStrategy.sourceDevicePixelSize,
365 expansionStrategy.orthogonalDistance
366 );
367 }
368 }
369 expansionStrategy.distanceMap->writeBytes(distanceMapRow1, expansionStrategy.rect.left(),
370 expansionStrategy.rect.bottom(), expansionStrategy.rect.width(), 1);
371 expansionStrategy.sourceDevice->writeBytes(deviceRow1, expansionStrategy.rect.left(),
372 expansionStrategy.rect.bottom(), expansionStrategy.rect.width(), 1);
373 progress.stepUp();
374
375 for (qint32 y = expansionStrategy.rect.bottom() - 1;
y >= expansionStrategy.rect.top(); --
y) {
376 expansionStrategy.distanceMap->readBytes(distanceMapRow2, expansionStrategy.rect.left(),
377 y, expansionStrategy.rect.width(), 1);
378 expansionStrategy.sourceDevice->readBytes(deviceRow2, expansionStrategy.rect.left(),
379 y, expansionStrategy.rect.width(), 1);
380
381 quint32 *bottomDistancePixel =
382 reinterpret_cast<quint32*>(distanceMapRow1) + expansionStrategy.rect.width() - 1;
383 quint32 *distancePixel =
384 reinterpret_cast<quint32*>(distanceMapRow2) + expansionStrategy.rect.width() - 1;
385 quint8 *bottomDevicePixel =
386 deviceRow1 + expansionStrategy.sourceDevicePixelSize * (expansionStrategy.rect.width() - 1);
387 quint8 *devicePixel =
388 deviceRow2 + expansionStrategy.sourceDevicePixelSize * (expansionStrategy.rect.width() - 1);
389
390 {
391 if (*distancePixel != 0) {
392 if (expansionStrategy.rect.width() > 1) {
393 expansionStrategy.updatePixel(
394 distancePixel, devicePixel,
395 bottomDistancePixel, bottomDevicePixel,
396 bottomDistancePixel - 1, bottomDevicePixel - expansionStrategy.sourceDevicePixelSize,
397 expansionStrategy.orthogonalDistance, expansionStrategy.diagonalDistance
398 );
399 } else {
400 expansionStrategy.updatePixel(
401 distancePixel, devicePixel,
402 bottomDistancePixel, bottomDevicePixel,
403 expansionStrategy.orthogonalDistance
404 );
405 }
406 }
407 --bottomDistancePixel;
408 --distancePixel;
409 bottomDevicePixel -= expansionStrategy.sourceDevicePixelSize;
410 devicePixel -= expansionStrategy.sourceDevicePixelSize;
411 }
412
413 for (qint32 x = 1;
x < expansionStrategy.rect.width() - 1;
414 ++
x, --bottomDistancePixel, --distancePixel,
415 bottomDevicePixel -= expansionStrategy.sourceDevicePixelSize,
416 devicePixel -= expansionStrategy.sourceDevicePixelSize) {
417
418 if (*distancePixel == 0) {
419 continue;
420 }
421 expansionStrategy.updatePixel(
422 distancePixel, devicePixel,
423 bottomDistancePixel + 1, bottomDevicePixel + expansionStrategy.sourceDevicePixelSize,
424 bottomDistancePixel, bottomDevicePixel,
425 bottomDistancePixel - 1, bottomDevicePixel - expansionStrategy.sourceDevicePixelSize,
426 distancePixel + 1, devicePixel + expansionStrategy.sourceDevicePixelSize,
427 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance,
428 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance
429 );
430 }
431
432 if (expansionStrategy.rect.width() > 1 && *distancePixel != 0) {
433 expansionStrategy.updatePixel(
434 distancePixel, devicePixel,
435 bottomDistancePixel + 1, bottomDevicePixel + expansionStrategy.sourceDevicePixelSize,
436 bottomDistancePixel, bottomDevicePixel,
437 distancePixel + 1, devicePixel + expansionStrategy.sourceDevicePixelSize,
438 expansionStrategy.diagonalDistance, expansionStrategy.orthogonalDistance,
439 expansionStrategy.orthogonalDistance
440 );
441 }
442
443 expansionStrategy.distanceMap->writeBytes(distanceMapRow2, expansionStrategy.rect.left(),
444 y, expansionStrategy.rect.width(), 1);
445 expansionStrategy.sourceDevice->writeBytes(deviceRow2, expansionStrategy.rect.left(),
y,
446 expansionStrategy.rect.width(), 1);
447
448 swapRowPointers(&distanceMapRow1, &distanceMapRow2, &deviceRow1, &deviceRow2);
449
450 progress.stepUp();
451 }
452
453 progress.complete();
454}
static void swapRowPointers(quint8 **distanceMapRow1, quint8 **distanceMapRow2, quint8 **deviceRow1, quint8 **deviceRow2)