annotate data/model/PowerOfSqrtTwoZoomConstraint.cpp @ 316:3a6725f285d6

* Make RemoteFile far more pervasive, and use it for local files as well so that we can handle both transparently. Make it shallow copy with reference counting, so it can be used by value without having to worry about the cache file lifetime. Use RemoteFile for MainWindow file-open functions, etc
author Chris Cannam
date Thu, 18 Oct 2007 15:31:20 +0000
parents 3a13b0d4934e
children 166c22eff678
rev   line source
Chris@147 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@147 2
Chris@147 3 /*
Chris@147 4 Sonic Visualiser
Chris@147 5 An audio file viewer and annotation editor.
Chris@147 6 Centre for Digital Music, Queen Mary, University of London.
Chris@147 7 This file copyright 2006 Chris Cannam.
Chris@147 8
Chris@147 9 This program is free software; you can redistribute it and/or
Chris@147 10 modify it under the terms of the GNU General Public License as
Chris@147 11 published by the Free Software Foundation; either version 2 of the
Chris@147 12 License, or (at your option) any later version. See the file
Chris@147 13 COPYING included with this distribution for more information.
Chris@147 14 */
Chris@147 15
Chris@147 16 #include "PowerOfSqrtTwoZoomConstraint.h"
Chris@147 17
Chris@147 18 #include <iostream>
Chris@147 19 #include <cmath>
Chris@147 20
Chris@147 21
Chris@147 22 size_t
Chris@147 23 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(size_t blockSize,
Chris@147 24 RoundingDirection dir) const
Chris@147 25 {
Chris@147 26 int type, power;
Chris@147 27 size_t rv = getNearestBlockSize(blockSize, type, power, dir);
Chris@147 28 return rv;
Chris@147 29 }
Chris@147 30
Chris@147 31 size_t
Chris@147 32 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(size_t blockSize,
Chris@147 33 int &type,
Chris@147 34 int &power,
Chris@147 35 RoundingDirection dir) const
Chris@147 36 {
Chris@147 37 // std::cerr << "given " << blockSize << std::endl;
Chris@147 38
Chris@147 39 size_t minCachePower = getMinCachePower();
Chris@147 40
Chris@147 41 if (blockSize < (1U << minCachePower)) {
Chris@147 42 type = -1;
Chris@147 43 power = 0;
Chris@147 44 float val = 1.0, prevVal = 1.0;
Chris@147 45 while (val + 0.01 < blockSize) {
Chris@147 46 prevVal = val;
Chris@147 47 val *= sqrt(2);
Chris@147 48 }
Chris@147 49 size_t rval;
Chris@147 50 if (dir == RoundUp) rval = size_t(val + 0.01);
Chris@147 51 else if (dir == RoundDown) rval = size_t(prevVal + 0.01);
Chris@147 52 else if (val - blockSize < blockSize - prevVal) rval = size_t(val + 0.01);
Chris@147 53 else rval = size_t(prevVal + 0.01);
Chris@147 54 // std::cerr << "returning " << rval << std::endl;
Chris@147 55 return rval;
Chris@147 56 }
Chris@147 57
Chris@147 58 unsigned int prevBase = (1 << minCachePower);
Chris@147 59 unsigned int prevPower = minCachePower;
Chris@147 60 unsigned int prevType = 0;
Chris@147 61
Chris@147 62 size_t result = 0;
Chris@147 63
Chris@147 64 for (unsigned int i = 0; ; ++i) {
Chris@147 65
Chris@147 66 power = minCachePower + i/2;
Chris@147 67 type = i % 2;
Chris@147 68
Chris@147 69 unsigned int base;
Chris@147 70 if (type == 0) {
Chris@147 71 base = (1 << power);
Chris@147 72 } else {
Chris@147 73 base = (((unsigned int)((1 << minCachePower) * sqrt(2) + 0.01))
Chris@147 74 << (power - minCachePower));
Chris@147 75 }
Chris@147 76
Chris@147 77 // std::cerr << "Testing base " << base << std::endl;
Chris@147 78 if (base >= blockSize) {
Chris@147 79 if (dir == RoundNearest) {
Chris@147 80 if (base - blockSize < blockSize - prevBase) {
Chris@147 81 dir = RoundUp;
Chris@147 82 } else {
Chris@147 83 dir = RoundDown;
Chris@147 84 }
Chris@147 85 }
Chris@147 86 if (dir == RoundUp) {
Chris@147 87 result = base;
Chris@147 88 break;
Chris@147 89 } else {
Chris@147 90 type = prevType;
Chris@147 91 power = prevPower;
Chris@147 92 result = prevBase;
Chris@147 93 break;
Chris@147 94 }
Chris@147 95 }
Chris@147 96
Chris@147 97 prevType = type;
Chris@147 98 prevPower = power;
Chris@147 99 prevBase = base;
Chris@147 100 }
Chris@147 101
Chris@147 102 if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
Chris@147 103 return result;
Chris@147 104 }