Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 9:561be41ad083
* Tweaked up spectrogram and added a colourmap rotation option
* Fleshed out the SV file reader code -- now we just need to hook it up
and watch it fall over
author | Chris Cannam |
---|---|
date | Mon, 16 Jan 2006 18:04:09 +0000 |
parents | 02aaea1ffaf7 |
children | 8f5b812baaee |
comparison
equal
deleted
inserted
replaced
8:06bba0b79b1c | 9:561be41ad083 |
---|---|
34 m_channel(0), | 34 m_channel(0), |
35 m_windowSize(1024), | 35 m_windowSize(1024), |
36 m_windowType(HanningWindow), | 36 m_windowType(HanningWindow), |
37 m_windowOverlap(50), | 37 m_windowOverlap(50), |
38 m_gain(1.0), | 38 m_gain(1.0), |
39 m_colourRotation(0), | |
39 m_maxFrequency(8000), | 40 m_maxFrequency(8000), |
40 m_colourScale(dBColourScale), | 41 m_colourScale(dBColourScale), |
41 m_colourScheme(DefaultColours), | 42 m_colourScheme(DefaultColours), |
42 m_frequencyScale(LinearFrequencyScale), | 43 m_frequencyScale(LinearFrequencyScale), |
43 m_cache(0), | 44 m_cache(0), |
106 list.push_back(tr("Colour Scale")); | 107 list.push_back(tr("Colour Scale")); |
107 list.push_back(tr("Window Type")); | 108 list.push_back(tr("Window Type")); |
108 list.push_back(tr("Window Size")); | 109 list.push_back(tr("Window Size")); |
109 list.push_back(tr("Window Overlap")); | 110 list.push_back(tr("Window Overlap")); |
110 list.push_back(tr("Gain")); | 111 list.push_back(tr("Gain")); |
112 list.push_back(tr("Colour Rotation")); | |
111 list.push_back(tr("Max Frequency")); | 113 list.push_back(tr("Max Frequency")); |
112 list.push_back(tr("Frequency Scale")); | 114 list.push_back(tr("Frequency Scale")); |
113 return list; | 115 return list; |
114 } | 116 } |
115 | 117 |
116 Layer::PropertyType | 118 Layer::PropertyType |
117 SpectrogramLayer::getPropertyType(const PropertyName &name) const | 119 SpectrogramLayer::getPropertyType(const PropertyName &name) const |
118 { | 120 { |
119 if (name == tr("Gain")) return RangeProperty; | 121 if (name == tr("Gain")) return RangeProperty; |
122 if (name == tr("Colour Rotation")) return RangeProperty; | |
120 return ValueProperty; | 123 return ValueProperty; |
121 } | 124 } |
122 | 125 |
123 QString | 126 QString |
124 SpectrogramLayer::getPropertyGroupName(const PropertyName &name) const | 127 SpectrogramLayer::getPropertyGroupName(const PropertyName &name) const |
125 { | 128 { |
126 if (name == tr("Window Size") || | 129 if (name == tr("Window Size") || |
127 name == tr("Window Overlap")) return tr("Window"); | 130 name == tr("Window Overlap")) return tr("Window"); |
128 if (name == tr("Gain") || | 131 if (name == tr("Gain") || |
132 name == tr("Colour Rotation") || | |
129 name == tr("Colour Scale")) return tr("Scale"); | 133 name == tr("Colour Scale")) return tr("Scale"); |
130 if (name == tr("Max Frequency") || | 134 if (name == tr("Max Frequency") || |
131 name == tr("Frequency Scale")) return tr("Frequency"); | 135 name == tr("Frequency Scale")) return tr("Frequency"); |
132 return QString(); | 136 return QString(); |
133 } | 137 } |
144 *max = 50; | 148 *max = 50; |
145 | 149 |
146 deft = lrint(log10(m_gain) * 20.0); | 150 deft = lrint(log10(m_gain) * 20.0); |
147 if (deft < *min) deft = *min; | 151 if (deft < *min) deft = *min; |
148 if (deft > *max) deft = *max; | 152 if (deft > *max) deft = *max; |
153 | |
154 } else if (name == tr("Colour Rotation")) { | |
155 | |
156 *min = 0; | |
157 *max = 256; | |
158 | |
159 deft = m_colourRotation; | |
149 | 160 |
150 } else if (name == tr("Colour Scale")) { | 161 } else if (name == tr("Colour Scale")) { |
151 | 162 |
152 *min = 0; | 163 *min = 0; |
153 *max = 3; | 164 *max = 3; |
216 return deft; | 227 return deft; |
217 } | 228 } |
218 | 229 |
219 QString | 230 QString |
220 SpectrogramLayer::getPropertyValueLabel(const PropertyName &name, | 231 SpectrogramLayer::getPropertyValueLabel(const PropertyName &name, |
221 int value) const | 232 int value) const |
222 { | 233 { |
223 if (name == tr("Colour")) { | 234 if (name == tr("Colour")) { |
224 switch (value) { | 235 switch (value) { |
225 default: | 236 default: |
226 case 0: return tr("Default"); | 237 case 0: return tr("Default"); |
293 void | 304 void |
294 SpectrogramLayer::setProperty(const PropertyName &name, int value) | 305 SpectrogramLayer::setProperty(const PropertyName &name, int value) |
295 { | 306 { |
296 if (name == tr("Gain")) { | 307 if (name == tr("Gain")) { |
297 setGain(pow(10, float(value)/20.0)); | 308 setGain(pow(10, float(value)/20.0)); |
309 } else if (name == tr("Colour Rotation")) { | |
310 setColourRotation(value); | |
298 } else if (name == tr("Colour")) { | 311 } else if (name == tr("Colour")) { |
299 if (m_view) m_view->setLightBackground(value == 2); | 312 if (m_view) m_view->setLightBackground(value == 2); |
300 switch (value) { | 313 switch (value) { |
301 default: | 314 default: |
302 case 0: setColourScheme(DefaultColours); break; | 315 case 0: setColourScheme(DefaultColours); break; |
352 m_mutex.lock(); | 365 m_mutex.lock(); |
353 m_cacheInvalid = true; | 366 m_cacheInvalid = true; |
354 m_pixmapCacheInvalid = true; | 367 m_pixmapCacheInvalid = true; |
355 | 368 |
356 m_channel = ch; | 369 m_channel = ch; |
370 | |
371 m_mutex.unlock(); | |
372 | |
357 emit layerParametersChanged(); | 373 emit layerParametersChanged(); |
358 | 374 |
359 m_mutex.unlock(); | |
360 fillCache(); | 375 fillCache(); |
361 | |
362 } | 376 } |
363 | 377 |
364 int | 378 int |
365 SpectrogramLayer::getChannel() const | 379 SpectrogramLayer::getChannel() const |
366 { | 380 { |
375 m_mutex.lock(); | 389 m_mutex.lock(); |
376 m_cacheInvalid = true; | 390 m_cacheInvalid = true; |
377 m_pixmapCacheInvalid = true; | 391 m_pixmapCacheInvalid = true; |
378 | 392 |
379 m_windowSize = ws; | 393 m_windowSize = ws; |
394 | |
395 m_mutex.unlock(); | |
396 | |
380 emit layerParametersChanged(); | 397 emit layerParametersChanged(); |
381 | 398 |
382 m_mutex.unlock(); | |
383 fillCache(); | 399 fillCache(); |
384 | |
385 } | 400 } |
386 | 401 |
387 size_t | 402 size_t |
388 SpectrogramLayer::getWindowSize() const | 403 SpectrogramLayer::getWindowSize() const |
389 { | 404 { |
398 m_mutex.lock(); | 413 m_mutex.lock(); |
399 m_cacheInvalid = true; | 414 m_cacheInvalid = true; |
400 m_pixmapCacheInvalid = true; | 415 m_pixmapCacheInvalid = true; |
401 | 416 |
402 m_windowOverlap = wi; | 417 m_windowOverlap = wi; |
418 | |
419 m_mutex.unlock(); | |
420 | |
403 emit layerParametersChanged(); | 421 emit layerParametersChanged(); |
404 | 422 |
405 m_mutex.unlock(); | |
406 fillCache(); | 423 fillCache(); |
407 } | 424 } |
408 | 425 |
409 size_t | 426 size_t |
410 SpectrogramLayer::getWindowOverlap() const | 427 SpectrogramLayer::getWindowOverlap() const |
420 m_mutex.lock(); | 437 m_mutex.lock(); |
421 m_cacheInvalid = true; | 438 m_cacheInvalid = true; |
422 m_pixmapCacheInvalid = true; | 439 m_pixmapCacheInvalid = true; |
423 | 440 |
424 m_windowType = w; | 441 m_windowType = w; |
442 | |
443 m_mutex.unlock(); | |
444 | |
425 emit layerParametersChanged(); | 445 emit layerParametersChanged(); |
426 | 446 |
427 m_mutex.unlock(); | |
428 fillCache(); | 447 fillCache(); |
429 } | 448 } |
430 | 449 |
431 WindowType | 450 WindowType |
432 SpectrogramLayer::getWindowType() const | 451 SpectrogramLayer::getWindowType() const |
442 m_mutex.lock(); | 461 m_mutex.lock(); |
443 m_cacheInvalid = true; | 462 m_cacheInvalid = true; |
444 m_pixmapCacheInvalid = true; | 463 m_pixmapCacheInvalid = true; |
445 | 464 |
446 m_gain = gain; | 465 m_gain = gain; |
466 | |
467 m_mutex.unlock(); | |
468 | |
447 emit layerParametersChanged(); | 469 emit layerParametersChanged(); |
448 | 470 |
449 m_mutex.unlock(); | |
450 fillCache(); | 471 fillCache(); |
451 } | 472 } |
452 | 473 |
453 float | 474 float |
454 SpectrogramLayer::getGain() const | 475 SpectrogramLayer::getGain() const |
464 m_mutex.lock(); | 485 m_mutex.lock(); |
465 // don't need to invalidate main cache here | 486 // don't need to invalidate main cache here |
466 m_pixmapCacheInvalid = true; | 487 m_pixmapCacheInvalid = true; |
467 | 488 |
468 m_maxFrequency = mf; | 489 m_maxFrequency = mf; |
490 | |
491 m_mutex.unlock(); | |
492 | |
469 emit layerParametersChanged(); | 493 emit layerParametersChanged(); |
470 | |
471 m_mutex.unlock(); | |
472 } | 494 } |
473 | 495 |
474 size_t | 496 size_t |
475 SpectrogramLayer::getMaxFrequency() const | 497 SpectrogramLayer::getMaxFrequency() const |
476 { | 498 { |
477 return m_maxFrequency; | 499 return m_maxFrequency; |
500 } | |
501 | |
502 void | |
503 SpectrogramLayer::setColourRotation(int r) | |
504 { | |
505 m_mutex.lock(); | |
506 // don't need to invalidate main cache here | |
507 m_pixmapCacheInvalid = true; | |
508 | |
509 if (r < 0) r = 0; | |
510 if (r > 256) r = 256; | |
511 int distance = r - m_colourRotation; | |
512 | |
513 if (distance != 0) { | |
514 rotateCacheColourmap(-distance); | |
515 m_colourRotation = r; | |
516 } | |
517 | |
518 m_mutex.unlock(); | |
519 | |
520 emit layerParametersChanged(); | |
478 } | 521 } |
479 | 522 |
480 void | 523 void |
481 SpectrogramLayer::setColourScale(ColourScale colourScale) | 524 SpectrogramLayer::setColourScale(ColourScale colourScale) |
482 { | 525 { |
485 m_mutex.lock(); | 528 m_mutex.lock(); |
486 m_cacheInvalid = true; | 529 m_cacheInvalid = true; |
487 m_pixmapCacheInvalid = true; | 530 m_pixmapCacheInvalid = true; |
488 | 531 |
489 m_colourScale = colourScale; | 532 m_colourScale = colourScale; |
490 emit layerParametersChanged(); | |
491 | 533 |
492 m_mutex.unlock(); | 534 m_mutex.unlock(); |
493 fillCache(); | 535 fillCache(); |
536 | |
537 emit layerParametersChanged(); | |
494 } | 538 } |
495 | 539 |
496 SpectrogramLayer::ColourScale | 540 SpectrogramLayer::ColourScale |
497 SpectrogramLayer::getColourScale() const | 541 SpectrogramLayer::getColourScale() const |
498 { | 542 { |
506 | 550 |
507 m_mutex.lock(); | 551 m_mutex.lock(); |
508 // don't need to invalidate main cache here | 552 // don't need to invalidate main cache here |
509 m_pixmapCacheInvalid = true; | 553 m_pixmapCacheInvalid = true; |
510 | 554 |
555 int formerColourRotation = m_colourRotation; | |
556 | |
511 m_colourScheme = scheme; | 557 m_colourScheme = scheme; |
512 setCacheColourmap(); | 558 setCacheColourmap(); |
559 | |
560 int distance = formerColourRotation - m_colourRotation; | |
561 | |
562 if (distance != 0) { | |
563 rotateCacheColourmap(-distance); | |
564 m_colourRotation = formerColourRotation; | |
565 } | |
566 | |
567 m_mutex.unlock(); | |
568 | |
513 emit layerParametersChanged(); | 569 emit layerParametersChanged(); |
514 | |
515 m_mutex.unlock(); | |
516 } | 570 } |
517 | 571 |
518 SpectrogramLayer::ColourScheme | 572 SpectrogramLayer::ColourScheme |
519 SpectrogramLayer::getColourScheme() const | 573 SpectrogramLayer::getColourScheme() const |
520 { | 574 { |
529 m_mutex.lock(); | 583 m_mutex.lock(); |
530 // don't need to invalidate main cache here | 584 // don't need to invalidate main cache here |
531 m_pixmapCacheInvalid = true; | 585 m_pixmapCacheInvalid = true; |
532 | 586 |
533 m_frequencyScale = frequencyScale; | 587 m_frequencyScale = frequencyScale; |
588 | |
589 m_mutex.unlock(); | |
590 | |
534 emit layerParametersChanged(); | 591 emit layerParametersChanged(); |
535 | |
536 m_mutex.unlock(); | |
537 } | 592 } |
538 | 593 |
539 SpectrogramLayer::FrequencyScale | 594 SpectrogramLayer::FrequencyScale |
540 SpectrogramLayer::getFrequencyScale() const | 595 SpectrogramLayer::getFrequencyScale() const |
541 { | 596 { |
676 } | 731 } |
677 | 732 |
678 m_cache->setColor | 733 m_cache->setColor |
679 (pixel, qRgb(colour.red(), colour.green(), colour.blue())); | 734 (pixel, qRgb(colour.red(), colour.green(), colour.blue())); |
680 } | 735 } |
736 | |
737 m_colourRotation = 0; | |
738 } | |
739 | |
740 void | |
741 SpectrogramLayer::rotateCacheColourmap(int distance) | |
742 { | |
743 QRgb newPixels[256]; | |
744 | |
745 newPixels[0] = m_cache->color(0); | |
746 | |
747 for (int pixel = 1; pixel < 256; ++pixel) { | |
748 int target = pixel + distance; | |
749 while (target < 1) target += 255; | |
750 while (target > 255) target -= 255; | |
751 newPixels[target] = m_cache->color(pixel); | |
752 } | |
753 | |
754 for (int pixel = 0; pixel < 256; ++pixel) { | |
755 m_cache->setColor(pixel, newPixels[pixel]); | |
756 } | |
681 } | 757 } |
682 | 758 |
683 bool | 759 bool |
684 SpectrogramLayer::fillCacheColumn(int column, double *input, | 760 SpectrogramLayer::fillCacheColumn(int column, double *input, |
685 fftw_complex *output, | 761 fftw_complex *output, |
686 fftw_plan plan, | 762 fftw_plan plan, |
763 size_t windowSize, | |
764 size_t increment, | |
687 const Window<double> &windower, | 765 const Window<double> &windower, |
688 bool lock) const | 766 bool lock) const |
689 { | 767 { |
690 size_t increment = m_windowSize - m_windowSize * m_windowOverlap / 100; | |
691 int startFrame = increment * column; | 768 int startFrame = increment * column; |
692 int endFrame = startFrame + m_windowSize; | 769 int endFrame = startFrame + windowSize; |
693 | 770 |
694 startFrame -= int(m_windowSize - increment) / 2; | 771 startFrame -= int(windowSize - increment) / 2; |
695 endFrame -= int(m_windowSize - increment) / 2; | 772 endFrame -= int(windowSize - increment) / 2; |
696 size_t pfx = 0; | 773 size_t pfx = 0; |
697 | 774 |
698 if (startFrame < 0) { | 775 if (startFrame < 0) { |
699 pfx = size_t(-startFrame); | 776 pfx = size_t(-startFrame); |
700 for (size_t i = 0; i < pfx; ++i) { | 777 for (size_t i = 0; i < pfx; ++i) { |
702 } | 779 } |
703 } | 780 } |
704 | 781 |
705 size_t got = m_model->getValues(m_channel, startFrame + pfx, | 782 size_t got = m_model->getValues(m_channel, startFrame + pfx, |
706 endFrame, input + pfx); | 783 endFrame, input + pfx); |
707 while (got + pfx < m_windowSize) { | 784 while (got + pfx < windowSize) { |
708 input[got + pfx] = 0.0; | 785 input[got + pfx] = 0.0; |
709 ++got; | 786 ++got; |
710 } | 787 } |
711 | 788 |
712 if (m_gain != 1.0) { | 789 if (m_gain != 1.0) { |
713 for (size_t i = 0; i < m_windowSize; ++i) { | 790 for (size_t i = 0; i < windowSize; ++i) { |
714 input[i] *= m_gain; | 791 input[i] *= m_gain; |
715 } | 792 } |
716 } | 793 } |
717 | 794 |
718 windower.cut(input); | 795 windower.cut(input); |
720 fftw_execute(plan); | 797 fftw_execute(plan); |
721 | 798 |
722 if (lock) m_mutex.lock(); | 799 if (lock) m_mutex.lock(); |
723 bool interrupted = false; | 800 bool interrupted = false; |
724 | 801 |
725 for (size_t i = 0; i < m_windowSize / 2; ++i) { | 802 for (size_t i = 0; i < windowSize / 2; ++i) { |
726 | 803 |
727 int value = 0; | 804 int value = 0; |
728 | 805 |
729 if (m_colourScale == PhaseColourScale) { | 806 if (m_colourScale == PhaseColourScale) { |
730 | 807 |
733 | 810 |
734 } else { | 811 } else { |
735 | 812 |
736 double mag = sqrt(output[i][0] * output[i][0] + | 813 double mag = sqrt(output[i][0] * output[i][0] + |
737 output[i][1] * output[i][1]); | 814 output[i][1] * output[i][1]); |
738 mag /= m_windowSize / 2; | 815 mag /= windowSize / 2; |
739 | 816 |
740 switch (m_colourScale) { | 817 switch (m_colourScale) { |
741 | 818 |
742 default: | 819 default: |
743 case LinearColourScale: | 820 case LinearColourScale: |
802 | 879 |
803 std::cerr << "SpectrogramLayer::CacheFillThread::run: model is ready" << std::endl; | 880 std::cerr << "SpectrogramLayer::CacheFillThread::run: model is ready" << std::endl; |
804 | 881 |
805 size_t start = m_layer.m_model->getStartFrame(); | 882 size_t start = m_layer.m_model->getStartFrame(); |
806 size_t end = m_layer.m_model->getEndFrame(); | 883 size_t end = m_layer.m_model->getEndFrame(); |
884 | |
885 WindowType windowType = m_layer.m_windowType; | |
807 size_t windowSize = m_layer.m_windowSize; | 886 size_t windowSize = m_layer.m_windowSize; |
808 size_t windowIncrement = m_layer.getWindowIncrement(); | 887 size_t windowIncrement = m_layer.getWindowIncrement(); |
809 | 888 |
810 size_t visibleStart = start; | 889 size_t visibleStart = start; |
811 size_t visibleEnd = end; | 890 size_t visibleEnd = end; |
820 } | 899 } |
821 visibleEnd = m_layer.m_view->getEndFrame(); | 900 visibleEnd = m_layer.m_view->getEndFrame(); |
822 } | 901 } |
823 | 902 |
824 delete m_layer.m_cache; | 903 delete m_layer.m_cache; |
825 m_layer.m_cache = new QImage((end - start) / windowIncrement + 1, | 904 size_t width = (end - start) / windowIncrement + 1; |
826 windowSize / 2, | 905 size_t height = windowSize / 2; |
827 QImage::Format_Indexed8); | 906 m_layer.m_cache = new QImage(width, height, |
907 QImage::Format_Indexed8); | |
908 | |
909 // If we're using JACK in mlock mode, this will be locked | |
910 // and we ought to unlock to avoid memory exhaustion. | |
911 // Shame it doesn't appear to be possible to allocate | |
912 // unlocked in the first place. | |
913 //!!! hm, I don't think this is working. | |
914 MUNLOCK((void *)m_layer.m_cache, width * height); | |
828 | 915 |
829 m_layer.setCacheColourmap(); | 916 m_layer.setCacheColourmap(); |
830 | 917 |
831 m_layer.m_cache->fill(0); | 918 m_layer.m_cache->fill(0); |
832 m_layer.m_mutex.unlock(); | 919 m_layer.m_mutex.unlock(); |
838 fftw_malloc(windowSize * sizeof(fftw_complex)); | 925 fftw_malloc(windowSize * sizeof(fftw_complex)); |
839 | 926 |
840 fftw_plan plan = fftw_plan_dft_r2c_1d(windowSize, input, | 927 fftw_plan plan = fftw_plan_dft_r2c_1d(windowSize, input, |
841 output, FFTW_ESTIMATE); | 928 output, FFTW_ESTIMATE); |
842 | 929 |
843 Window<double> windower(m_layer.m_windowType, m_layer.m_windowSize); | 930 Window<double> windower(windowType, windowSize); |
844 | 931 |
845 if (!plan) { | 932 if (!plan) { |
846 std::cerr << "WARNING: fftw_plan_dft_r2c_1d(" << windowSize << ") failed!" << std::endl; | 933 std::cerr << "WARNING: fftw_plan_dft_r2c_1d(" << windowSize << ") failed!" << std::endl; |
847 fftw_free(input); | 934 fftw_free(input); |
848 fftw_free(output); | 935 fftw_free(output); |
861 m_layer.m_mutex.lock(); | 948 m_layer.m_mutex.lock(); |
862 | 949 |
863 for (size_t f = visibleStart; f < visibleEnd; f += windowIncrement) { | 950 for (size_t f = visibleStart; f < visibleEnd; f += windowIncrement) { |
864 | 951 |
865 m_layer.fillCacheColumn(int((f - start) / windowIncrement), | 952 m_layer.fillCacheColumn(int((f - start) / windowIncrement), |
866 input, output, plan, windower, false); | 953 input, output, plan, |
954 windowSize, windowIncrement, | |
955 windower, false); | |
867 | 956 |
868 m_layer.m_mutex.unlock(); | 957 m_layer.m_mutex.unlock(); |
869 m_layer.m_mutex.lock(); | 958 m_layer.m_mutex.lock(); |
870 | 959 |
871 if (m_layer.m_cacheInvalid || m_layer.m_exiting) { | 960 if (m_layer.m_cacheInvalid || m_layer.m_exiting) { |
890 if (!interrupted && doVisibleFirst) { | 979 if (!interrupted && doVisibleFirst) { |
891 | 980 |
892 for (size_t f = visibleEnd; f < end; f += windowIncrement) { | 981 for (size_t f = visibleEnd; f < end; f += windowIncrement) { |
893 | 982 |
894 if (!m_layer.fillCacheColumn(int((f - start) / windowIncrement), | 983 if (!m_layer.fillCacheColumn(int((f - start) / windowIncrement), |
895 input, output, plan, windower, true)) { | 984 input, output, plan, |
985 windowSize, windowIncrement, | |
986 windower, true)) { | |
896 interrupted = true; | 987 interrupted = true; |
897 m_fillExtent = 0; | 988 m_fillExtent = 0; |
898 break; | 989 break; |
899 } | 990 } |
900 | 991 |
919 size_t baseCompletion = m_fillCompletion; | 1010 size_t baseCompletion = m_fillCompletion; |
920 | 1011 |
921 for (size_t f = start; f < remainingEnd; f += windowIncrement) { | 1012 for (size_t f = start; f < remainingEnd; f += windowIncrement) { |
922 | 1013 |
923 if (!m_layer.fillCacheColumn(int((f - start) / windowIncrement), | 1014 if (!m_layer.fillCacheColumn(int((f - start) / windowIncrement), |
924 input, output, plan, windower, true)) { | 1015 input, output, plan, |
1016 windowSize, windowIncrement, | |
1017 windower, true)) { | |
925 interrupted = true; | 1018 interrupted = true; |
926 m_fillExtent = 0; | 1019 m_fillExtent = 0; |
927 break; | 1020 break; |
928 } | 1021 } |
929 | 1022 |
1346 } | 1439 } |
1347 } | 1440 } |
1348 } | 1441 } |
1349 | 1442 |
1350 if (divisor > 0.0) { | 1443 if (divisor > 0.0) { |
1444 | |
1351 int pixel = int(total / divisor); | 1445 int pixel = int(total / divisor); |
1352 if (pixel > 255) pixel = 255; | 1446 if (pixel > 255) pixel = 255; |
1353 if (pixel < 1) pixel = 1; | 1447 if (pixel < 1) pixel = 1; |
1354 assert(x <= scaled.width()); | 1448 assert(x <= scaled.width()); |
1355 scaled.setPixel(x, y, m_cache->color(pixel)); | 1449 scaled.setPixel(x, y, m_cache->color(pixel)); |
1450 /* | |
1451 float pixel = total / divisor; | |
1452 float lq = pixel - int(pixel); | |
1453 float hq = int(pixel) + 1 - pixel; | |
1454 int pixNum = int(pixel); | |
1455 QRgb low = m_cache->color(pixNum > 255 ? 255 : pixNum); | |
1456 QRgb high = m_cache->color(pixNum > 254 ? 255 : pixNum + 1); | |
1457 QRgb mixed = qRgb | |
1458 (qRed(low) * lq + qRed(high) * hq + 0.01, | |
1459 qGreen(low) * lq + qGreen(high) * hq + 0.01, | |
1460 qBlue(low) * lq + qBlue(high) * hq + 0.01); | |
1461 scaled.setPixel(x, y, mixed); | |
1462 */ | |
1356 } else { | 1463 } else { |
1357 assert(x <= scaled.width()); | 1464 assert(x <= scaled.width()); |
1358 scaled.setPixel(x, y, qRgb(0, 0, 0)); | 1465 scaled.setPixel(x, y, qRgb(0, 0, 0)); |
1359 } | 1466 } |
1360 } | 1467 } |