comparison layer/Colour3DPlotLayer.cpp @ 812:6c52314b31b0

Dense colour 3d plot layers should be scrollable, I think; and some tidying, debug stuff, and minor optimisations
author Chris Cannam
date Tue, 01 Jul 2014 15:32:54 +0100
parents 1d526ba11a24
children 2d4af227fd32
comparison
equal deleted inserted replaced
811:c4ef666721bf 812:6c52314b31b0
507 Colour3DPlotLayer::setLayerDormant(const View *v, bool dormant) 507 Colour3DPlotLayer::setLayerDormant(const View *v, bool dormant)
508 { 508 {
509 if (dormant) { 509 if (dormant) {
510 510
511 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 511 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
512 SVDEBUG << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")" 512 cerr << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")"
513 << endl; 513 << endl;
514 #endif 514 #endif
515 515
516 if (isLayerDormant(v)) { 516 if (isLayerDormant(v)) {
517 return; 517 return;
528 } 528 }
529 529
530 bool 530 bool
531 Colour3DPlotLayer::isLayerScrollable(const View *v) const 531 Colour3DPlotLayer::isLayerScrollable(const View *v) const
532 { 532 {
533 if (m_normalizeVisibleArea) return false; 533 if (m_normalizeVisibleArea) {
534 return false;
535 }
536 if (shouldPaintDenseIn(v)) {
537 return true;
538 }
534 QPoint discard; 539 QPoint discard;
535 return !v->shouldIlluminateLocalFeatures(this, discard); 540 return !v->shouldIlluminateLocalFeatures(this, discard);
536 } 541 }
537 542
538 bool 543 bool
684 689
685 float srRatio = 690 float srRatio =
686 float(v->getViewManager()->getMainModelSampleRate()) / 691 float(v->getViewManager()->getMainModelSampleRate()) /
687 float(m_model->getSampleRate()); 692 float(m_model->getSampleRate());
688 693
689 int sx0 = int((v->getFrameForX(x) / srRatio - long(modelStart)) / 694 int sx0 = int((v->getFrameForX(x) / srRatio - modelStart) /
690 long(modelResolution)); 695 modelResolution);
691 696
692 int f0 = sx0 * modelResolution; 697 int f0 = sx0 * modelResolution;
693 int f1 = f0 + modelResolution; 698 int f1 = f0 + modelResolution;
694 699
695 int sh = m_model->getHeight(); 700 int sh = m_model->getHeight();
705 710
706 // float binHeight = float(v->height()) / (symax - symin); 711 // float binHeight = float(v->height()) / (symax - symin);
707 // int sy = int((v->height() - y) / binHeight) + symin; 712 // int sy = int((v->height() - y) / binHeight) + symin;
708 713
709 int sy = getBinForY(v, y); 714 int sy = getBinForY(v, y);
715
716 if (sy < 0 || sy >= m_model->getHeight()) {
717 return "";
718 }
710 719
711 if (m_invertVertical) sy = m_model->getHeight() - sy - 1; 720 if (m_invertVertical) sy = m_model->getHeight() - sy - 1;
712 721
713 float value = m_model->getValueAt(sx0, sy); 722 float value = m_model->getValueAt(sx0, sy);
714 723
901 } 910 }
902 911
903 DenseThreeDimensionalModel::Column 912 DenseThreeDimensionalModel::Column
904 Colour3DPlotLayer::getColumn(int col) const 913 Colour3DPlotLayer::getColumn(int col) const
905 { 914 {
915 Profiler profiler("Colour3DPlotLayer::getColumn");
916
906 DenseThreeDimensionalModel::Column values = m_model->getColumn(col); 917 DenseThreeDimensionalModel::Column values = m_model->getColumn(col);
907 while (values.size() < m_model->getHeight()) values.push_back(0.f); 918 while (values.size() < m_model->getHeight()) values.push_back(0.f);
908 if (!m_normalizeColumns && !m_normalizeHybrid) return values; 919 if (!m_normalizeColumns && !m_normalizeHybrid) return values;
909 920
910 float colMax = 0.f, colMin = 0.f; 921 float colMax = 0.f, colMin = 0.f;
939 } 950 }
940 951
941 void 952 void
942 Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const 953 Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const
943 { 954 {
944 Profiler profiler("Colour3DPlotLayer::fillCache"); 955 Profiler profiler("Colour3DPlotLayer::fillCache", true);
945 956
946 int modelStart = m_model->getStartFrame(); 957 int modelStart = m_model->getStartFrame();
947 int modelEnd = m_model->getEndFrame(); 958 int modelEnd = m_model->getEndFrame();
948 int modelResolution = m_model->getResolution(); 959 int modelResolution = m_model->getResolution();
949 960
950 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
951 SVDEBUG << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << endl;
952 #endif
953
954 int modelStartBin = modelStart / modelResolution; 961 int modelStartBin = modelStart / modelResolution;
955 int modelEndBin = modelEnd / modelResolution; 962 int modelEndBin = modelEnd / modelResolution;
963
964 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
965 cerr << "Colour3DPlotLayer::fillCache: range " << firstBin << " -> " << lastBin << " of model range " << modelStartBin << " -> " << modelEndBin << " (model resolution " << modelResolution << ")" << endl;
966 #endif
956 967
957 int cacheWidth = modelEndBin - modelStartBin + 1; 968 int cacheWidth = modelEndBin - modelStartBin + 1;
958 if (lastBin > modelEndBin) cacheWidth = lastBin - modelStartBin + 1; 969 if (lastBin > modelEndBin) cacheWidth = lastBin - modelStartBin + 1;
959 int cacheHeight = m_model->getHeight(); 970 int cacheHeight = m_model->getHeight();
960 971
961 if (m_cache && (m_cache->height() != int(cacheHeight))) { 972 if (m_cache && m_cache->height() != cacheHeight) {
962 // height has changed: delete everything rather than resizing 973 // height has changed: delete everything rather than resizing
974 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
975 cerr << "Colour3DPlotLayer::fillCache: Cache height has changed, recreating" << endl;
976 #endif
963 delete m_cache; 977 delete m_cache;
964 delete m_peaksCache; 978 delete m_peaksCache;
965 m_cache = 0; 979 m_cache = 0;
966 m_peaksCache = 0; 980 m_peaksCache = 0;
967 } 981 }
968 982
969 if (m_cache && (m_cache->width() != int(cacheWidth))) { 983 if (m_cache && m_cache->width() != cacheWidth) {
970 // width has changed and we have an existing cache: resize it 984 // width has changed and we have an existing cache: resize it
985 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
986 cerr << "Colour3DPlotLayer::fillCache: Cache width has changed, resizing existing cache" << endl;
987 #endif
971 QImage *newCache = 988 QImage *newCache =
972 new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight)); 989 new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight));
973 delete m_cache; 990 delete m_cache;
974 m_cache = newCache; 991 m_cache = newCache;
975 if (m_peaksCache) { 992 if (m_peaksCache) {
980 m_peaksCache = newPeaksCache; 997 m_peaksCache = newPeaksCache;
981 } 998 }
982 } 999 }
983 1000
984 if (!m_cache) { 1001 if (!m_cache) {
1002 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1003 cerr << "Colour3DPlotLayer::fillCache: Have no cache, making one" << endl;
1004 #endif
985 m_cache = new QImage 1005 m_cache = new QImage
986 (cacheWidth, cacheHeight, QImage::Format_Indexed8); 1006 (cacheWidth, cacheHeight, QImage::Format_Indexed8);
987 // No longer exists in Qt5: m_cache->setNumColors(256); 1007 m_cache->setColorCount(256);
988 m_cache->fill(0); 1008 m_cache->fill(0);
989 if (!m_normalizeVisibleArea) { 1009 if (!m_normalizeVisibleArea) {
990 m_peaksCache = new QImage 1010 m_peaksCache = new QImage
991 (cacheWidth / m_peakResolution + 1, cacheHeight, 1011 (cacheWidth / m_peakResolution + 1, cacheHeight,
992 QImage::Format_Indexed8); 1012 QImage::Format_Indexed8);
993 // No longer exists in Qt5: m_peaksCache->setNumColors(256); 1013 m_peaksCache->setColorCount(256);
994 m_peaksCache->fill(0); 1014 m_peaksCache->fill(0);
995 } else if (m_peaksCache) { 1015 } else if (m_peaksCache) {
996 delete m_peaksCache; 1016 delete m_peaksCache;
997 m_peaksCache = 0; 1017 m_peaksCache = 0;
998 } 1018 }
999 m_cacheValidStart = 0; 1019 m_cacheValidStart = 0;
1000 m_cacheValidEnd = 0; 1020 m_cacheValidEnd = 0;
1001 } 1021 }
1002 1022
1003 // cerr << "cache size = " << m_cache->width() << "x" << m_cache->height() 1023 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1004 // << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl; 1024 cerr << "cache size = " << m_cache->width() << "x" << m_cache->height()
1025 << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl;
1026 #endif
1005 1027
1006 if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) { 1028 if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) {
1007 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1029 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1008 cerr << "Cache is valid in this region already" << endl; 1030 cerr << "Cache is valid in this region already" << endl;
1009 #endif 1031 #endif
1032 m_cacheValidStart = std::min(fillStart, m_cacheValidStart); 1054 m_cacheValidStart = std::min(fillStart, m_cacheValidStart);
1033 m_cacheValidEnd = std::max(fillEnd, m_cacheValidEnd); 1055 m_cacheValidEnd = std::max(fillEnd, m_cacheValidEnd);
1034 1056
1035 } else { 1057 } else {
1036 1058
1037 // the only valid area, ever, is the currently visible one 1059 // when normalising the visible area, the only valid area,
1060 // ever, is the currently visible one
1038 1061
1039 m_cacheValidStart = fillStart; 1062 m_cacheValidStart = fillStart;
1040 m_cacheValidEnd = fillEnd; 1063 m_cacheValidEnd = fillEnd;
1041 } 1064 }
1042 1065
1043 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1066 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1044 cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << endl; 1067 cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl;
1045 #endif 1068 #endif
1046 1069
1047 DenseThreeDimensionalModel::Column values; 1070 DenseThreeDimensionalModel::Column values;
1048 1071
1049 float min = m_model->getMinimumLevel(); 1072 float min = m_model->getMinimumLevel();
1122 peaks = new int[cacheHeight]; 1145 peaks = new int[cacheHeight];
1123 for (int y = 0; y < cacheHeight; ++y) { 1146 for (int y = 0; y < cacheHeight; ++y) {
1124 peaks[y] = 0; 1147 peaks[y] = 0;
1125 } 1148 }
1126 } 1149 }
1150
1151 Profiler profiler2("Colour3DPlotLayer::fillCache: filling", true);
1127 1152
1128 for (int c = fillStart; c <= fillEnd; ++c) { 1153 for (int c = fillStart; c <= fillEnd; ++c) {
1129 1154
1130 values = getColumn(c); 1155 values = getColumn(c);
1131 1156
1202 } 1227 }
1203 1228
1204 delete[] peaks; 1229 delete[] peaks;
1205 } 1230 }
1206 1231
1232 bool
1233 Colour3DPlotLayer::shouldPaintDenseIn(const View *v) const
1234 {
1235 if (!m_model || !v || !(v->getViewManager())) {
1236 return false;
1237 }
1238 float srRatio =
1239 float(v->getViewManager()->getMainModelSampleRate()) /
1240 float(m_model->getSampleRate());
1241 if (m_opaque ||
1242 m_smooth ||
1243 m_model->getHeight() >= v->height() ||
1244 ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) {
1245 return true;
1246 }
1247 return false;
1248 }
1249
1207 void 1250 void
1208 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const 1251 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const
1209 { 1252 {
1210 /* 1253 /*
1211 if (m_model) { 1254 if (m_model) {
1212 SVDEBUG << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << m_model->shouldUseLogValueScale() << endl; 1255 SVDEBUG << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << m_model->shouldUseLogValueScale() << endl;
1213 } 1256 }
1214 */ 1257 */
1215 Profiler profiler("Colour3DPlotLayer::paint"); 1258 Profiler profiler("Colour3DPlotLayer::paint");
1216 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1259 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1217 SVDEBUG << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << endl; 1260 cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", rect is (" << rect.x() << "," << rect.y() << ") " << rect.width() << "x" << rect.height() << endl;
1218 #endif 1261 #endif
1219 1262
1220 int completion = 0; 1263 int completion = 0;
1221 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) { 1264 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) {
1222 if (completion > 0) { 1265 if (completion > 0) {
1248 1291
1249 float srRatio = 1292 float srRatio =
1250 float(v->getViewManager()->getMainModelSampleRate()) / 1293 float(v->getViewManager()->getMainModelSampleRate()) /
1251 float(m_model->getSampleRate()); 1294 float(m_model->getSampleRate());
1252 1295
1253 int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) 1296 int sx0 = int((v->getFrameForX(x0) / srRatio - modelStart)
1254 / long(modelResolution)); 1297 / modelResolution);
1255 int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) 1298 int sx1 = int((v->getFrameForX(x1) / srRatio - modelStart)
1256 / long(modelResolution)); 1299 / modelResolution);
1257 int sh = m_model->getHeight(); 1300 int sh = m_model->getHeight();
1258 1301
1259 int symin = m_miny; 1302 int symin = m_miny;
1260 int symax = m_maxy; 1303 int symax = m_maxy;
1261 if (symax <= symin) { 1304 if (symax <= symin) {
1268 if (sx0 > 0) --sx0; 1311 if (sx0 > 0) --sx0;
1269 fillCache(sx0 < 0 ? 0 : sx0, 1312 fillCache(sx0 < 0 ? 0 : sx0,
1270 sx1 < 0 ? 0 : sx1); 1313 sx1 < 0 ? 0 : sx1);
1271 1314
1272 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1315 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1273 SVDEBUG << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl; 1316 cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl;
1274 #endif 1317 #endif
1275 1318
1276 if (m_opaque || 1319 if (shouldPaintDenseIn(v)) {
1277 m_smooth ||
1278 int(m_model->getHeight()) >= v->height() ||
1279 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) {
1280 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1320 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1281 SVDEBUG << "calling paintDense" << endl; 1321 cerr << "calling paintDense" << endl;
1282 #endif 1322 #endif
1283 paintDense(v, paint, rect); 1323 paintDense(v, paint, rect);
1284 return; 1324 return;
1285 } 1325 }
1286 1326
1287 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1327 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1288 SVDEBUG << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl; 1328 cerr << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl;
1289 cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << endl; 1329 cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << endl;
1290 #endif 1330 #endif
1291 1331
1292 QPoint illuminatePos; 1332 QPoint illuminatePos;
1293 bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos); 1333 bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos);
1294 char labelbuf[10]; 1334 char labelbuf[10];
1295 1335
1296 for (int sx = sx0; sx <= sx1; ++sx) { 1336 for (int sx = sx0; sx <= sx1; ++sx) {
1297 1337
1298 int fx = sx * int(modelResolution); 1338 int fx = sx * modelResolution;
1299 1339
1300 if (fx + int(modelResolution) <= int(modelStart) || 1340 if (fx + modelResolution <= modelStart || fx > modelEnd) continue;
1301 fx > int(modelEnd)) continue; 1341
1302 1342 int rx0 = v->getXForFrame(int((fx + modelStart) * srRatio));
1303 int rx0 = v->getXForFrame(int((fx + int(modelStart)) * srRatio)); 1343 int rx1 = v->getXForFrame(int((fx + modelStart + modelResolution + 1) * srRatio));
1304 int rx1 = v->getXForFrame(int((fx + int(modelStart) + int(modelResolution) + 1) * srRatio));
1305 1344
1306 int rw = rx1 - rx0; 1345 int rw = rx1 - rx0;
1307 if (rw < 1) rw = 1; 1346 if (rw < 1) rw = 1;
1308 1347
1309 bool showLabel = (rw > 10 && 1348 bool showLabel = (rw > 10 &&
1369 } 1408 }
1370 1409
1371 void 1410 void
1372 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const 1411 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const
1373 { 1412 {
1374 Profiler profiler("Colour3DPlotLayer::paintDense"); 1413 Profiler profiler("Colour3DPlotLayer::paintDense", true);
1375 if (!m_cache) return; 1414 if (!m_cache) return;
1376 1415
1377 float modelStart = m_model->getStartFrame(); 1416 float modelStart = m_model->getStartFrame();
1378 float modelResolution = m_model->getResolution(); 1417 float modelResolution = m_model->getResolution();
1379 1418
1404 memset(peaks, 0, w); 1443 memset(peaks, 0, w);
1405 1444
1406 int zoomLevel = v->getZoomLevel(); 1445 int zoomLevel = v->getZoomLevel();
1407 1446
1408 QImage *source = m_cache; 1447 QImage *source = m_cache;
1409 1448
1410 SVDEBUG << "modelResolution " << modelResolution << ", srRatio " 1449 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1411 << srRatio << ", m_peakResolution " << m_peakResolution 1450 cerr << "modelResolution " << modelResolution << ", srRatio "
1412 << ", zoomLevel " << zoomLevel << ", result " 1451 << srRatio << ", m_peakResolution " << m_peakResolution
1413 << ((modelResolution * srRatio * m_peakResolution) / zoomLevel) 1452 << ", zoomLevel " << zoomLevel << ", result "
1414 << endl; 1453 << ((modelResolution * srRatio * m_peakResolution) / zoomLevel)
1454 << endl;
1455 #endif
1415 1456
1416 if (m_peaksCache) { 1457 if (m_peaksCache) {
1417 if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) { 1458 if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) {
1418 SVDEBUG << "using peaks cache" << endl; 1459 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1460 cerr << "using peaks cache" << endl;
1461 #endif
1419 source = m_peaksCache; 1462 source = m_peaksCache;
1420 modelResolution *= m_peakResolution; 1463 modelResolution *= m_peakResolution;
1421 } else { 1464 } else {
1422 SVDEBUG << "not using peaks cache" << endl; 1465 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1466 cerr << "not using peaks cache" << endl;
1467 #endif
1423 } 1468 }
1424 } else { 1469 } else {
1425 SVDEBUG << "have no peaks cache" << endl; 1470 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1426 } 1471 cerr << "have no peaks cache" << endl;
1427 1472 #endif
1428 int psy1i = -1; 1473 }
1474
1429 int sw = source->width(); 1475 int sw = source->width();
1430 1476
1431 long xf = -1; 1477 int xf = -1;
1432 long nxf = v->getFrameForX(x0); 1478 int nxf = v->getFrameForX(x0);
1433 1479
1434 float epsilon = 0.000001; 1480 float epsilon = 0.000001;
1435 1481
1436 #ifdef __GNUC__ 1482 #ifdef __GNUC__
1437 float sxa[w * 2]; 1483 float sxa[w * 2];
1450 sxa[x*2 + 1] = sx1; 1496 sxa[x*2 + 1] = sx1;
1451 } 1497 }
1452 1498
1453 float logmin = symin+1, logmax = symax+1; 1499 float logmin = symin+1, logmax = symax+1;
1454 LogRange::mapRange(logmin, logmax); 1500 LogRange::mapRange(logmin, logmax);
1501
1502 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1503 cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl;
1504 #endif
1455 1505
1456 if (m_smooth) { 1506 if (m_smooth) {
1457 1507
1458 for (int y = 0; y < h; ++y) { 1508 for (int y = 0; y < h; ++y) {
1459 1509
1523 targetLine[x] = uchar(vi); 1573 targetLine[x] = uchar(vi);
1524 } 1574 }
1525 } 1575 }
1526 } else { 1576 } else {
1527 1577
1578 float sy0 = getBinForY(v, 0);
1579
1580 int psy0i = -1, psy1i = -1;
1581
1528 for (int y = 0; y < h; ++y) { 1582 for (int y = 0; y < h; ++y) {
1529 1583
1530 float sy0, sy1; 1584 float sy1 = sy0;
1531
1532 sy0 = getBinForY(v, y + 1); 1585 sy0 = getBinForY(v, y + 1);
1533 sy1 = getBinForY(v, y);
1534 1586
1535 int sy0i = int(sy0 + epsilon); 1587 int sy0i = int(sy0 + epsilon);
1536 int sy1i = int(sy1); 1588 int sy1i = int(sy1);
1537 1589
1538 uchar *targetLine = img.scanLine(y); 1590 uchar *targetLine = img.scanLine(y);
1539 1591
1540 if (sy0i == sy1i && sy0i == psy1i) { // same source scan line as just computed 1592 if (sy0i == psy0i && sy1i == psy1i) {
1593 // same source scan line as just computed
1541 goto copy; 1594 goto copy;
1542 } 1595 }
1596
1597 psy0i = sy0i;
1598 psy1i = sy1i;
1543 1599
1544 for (int x = 0; x < w; ++x) { 1600 for (int x = 0; x < w; ++x) {
1545 peaks[x] = 0; 1601 peaks[x] = 0;
1546 } 1602 }
1547 1603