9#include "ViewportBuffer.h" 
   10#include "ViewportBufferAction.h" 
   11#include "ViewportBufferStretch.h" 
   12#include "ViewportBufferFill.h" 
   13#include "ViewportBufferTransform.h" 
   15#include <QApplication> 
   21#include "CubeDataThread.h" 
   22#include "CubeViewport.h" 
   23#include "SpecialPixel.h" 
   27#define round(x) ((x) > 0.0 ? (x) + 0.5 : (x) - 0.5) 
   50    p_actions = 
new QQueue< ViewportBufferAction * >();
 
   62    p_bricksOrdered = 
true;
 
   64    connect(
this, SIGNAL(
ReadCube(
int, 
int, 
int, 
int, 
int, 
int, 
void *)),
 
 
   79    disconnect(
this, SIGNAL(
ReadCube(
int, 
int, 
int, 
int, 
int, 
int, 
void *)),
 
 
  148        for(
int x = rect.left(); x <= rect.right(); x ++) {
 
  156          if (samp < data->Sample())
 
  160          if (line < data->Line())
 
  167          int brickIndex = data->
Index((
int)(samp + 0.5), (
int)(line + 0.5), 
p_band);
 
  172            else if(brickIndex >= data->
size()) {
 
  176              if(yIndex < 0 || xIndex < 0 || yIndex >= (
int) 
p_buffer.size() ||
 
  177                xIndex >= (int) 
p_buffer.at(yIndex).size()) {
 
  179                                 "index out of range",
 
  183                  p_buffer.at(yIndex).at(xIndex) = data->
at(brickIndex);
 
  191                       "into buffer", _FILEINFO_);
 
 
  206                                 const Brick *brick) {
 
  207    if(
this != requester)
 
  217        !curAction->started()) {
 
  223    const QRect *rect = fill->
getRect();
 
  231    bool brickOrderCorrection = p_bricksOrdered;
 
  232    if (curBrickLine != nextBrickLine &&
 
  233        nextBrickLine == (
int) (brick->Line() + 0.5)) {
 
  235      p_bricksOrdered = 
false;
 
  238      p_bricksOrdered = 
true;
 
  244    for(
int x = rect->left(); x <= rect->right(); x++) {
 
  253      int brickIndex = (int)(samp + 0.5) - brick->Sample();
 
  256        p_buffer.at(yIndex).at(xIndex) = brick->at(0);
 
  258      else if(brickIndex  >= brick->size()) {
 
  259        p_buffer.at(yIndex).at(xIndex) = brick->at(brick->size() - 1);
 
  262        if(yIndex < 0 || xIndex < 0 || yIndex >= (
int) 
p_buffer.size() ||
 
  263            xIndex >= (int) 
p_buffer.at(yIndex).size()) {
 
  264          IString msg = 
"An index out of range error was detected. ";
 
  267            msg += 
"The Y-Index [" + 
IString(yIndex) + 
"] is less than 0";
 
  269            msg += 
"The X-Index [" + 
IString(xIndex) + 
"] is less than 0";
 
  270          else if(yIndex > (
int)
p_buffer.size())
 
  271            msg += 
"The Y-Index [" + 
IString(yIndex) + 
"] is greater than the " 
  273          else if(xIndex > (
int)
p_buffer.at(yIndex).size())
 
  274            msg += 
"The X-Index [" + 
IString(xIndex) + 
" is greater than the " 
  280          p_buffer.at(yIndex).at(xIndex) = brick->at(brickIndex);
 
  288      if (p_bricksOrdered) {
 
  292        if (brickOrderCorrection) {
 
 
  344    if(line < 0 || line >= (
int)
p_buffer.size()) {
 
  346                       "Invalid call to getLine",
 
 
  362    int startx, starty, endx, endy;
 
  367    double startSamp, startLine;
 
  381    if(endx < 0 || endy < 0)
 
  384    double endSamp = -1, endLine = -1;
 
  387    if(endSamp > rightmost)
 
  390    if(endLine > bottommost)
 
  406    if(endy >= 
p_viewport->viewport()->height()) {
 
  410    return QRect(startx, starty, endx - startx + 1, endy - starty + 1);
 
 
  446    double ssamp, esamp, sline, eline;
 
  450    QList<double> boundingRect;
 
  452    boundingRect.insert(
rectLeft, ssamp);
 
  453    boundingRect.insert(
rectTop, sline);
 
 
  494    QRect someRect, 
bool useOldY) {
 
  495    QScrollBar *hsb = 
p_viewport->horizontalScrollBar();
 
  496    int xConstCoef = hsb->value();
 
  497    xConstCoef -= 
p_viewport->viewport()->width() / 2;
 
  502    if(!someRect.isValid()) {
 
  515    double yScale = xScale;
 
  527        xScale, yConstCoef, yScale, topLeft);
 
 
  544    QRect &rect = *fill->
getRect();
 
  550    int brickWidth = (int)(ceil(esamp) - floor(ssamp)) + 1;
 
  556    int roundedSamp = (int)(ssamp + 0.5);
 
  557    int roundedLine = (int)(line + 0.5);
 
  560                  roundedLine, 
p_band, 
this);
 
 
  577    bool doNextAction = 
false;
 
  595      doNextAction = !curAction->started();
 
  598    while(doNextAction) {
 
  614        doNextAction = !curAction->started();
 
 
  647    double totalFillArea = 0.0;
 
  651    for(
int actionIndex = 0; actionIndex < 
p_actions->size(); actionIndex ++) {
 
  657        QRect unfilledRect(*fill->
getRect());
 
  659        totalFillArea += unfilledRect.width() * unfilledRect.height();
 
  663    return totalFillArea;
 
 
  677    int bufferWidth  = currentBufferRect.width();
 
  678    int bufferHeight = currentBufferRect.height();
 
  682    for(
int actionIndex = 0; actionIndex < 
p_actions->size(); actionIndex ++) {
 
  693        if(abs(totalXShift) >= bufferWidth)
 
  695        if(abs(totalYShift) >= bufferHeight)
 
  710        if(abs(totalXShift) >= bufferWidth)
 
  712        if(abs(totalYShift) >= bufferHeight)
 
 
  730    if(currentBufferRect.width() == 0 || currentBufferRect.height() == 0) {
 
  734    for(
int actionIndex = 0; actionIndex < 
p_actions->size(); actionIndex ++) {
 
 
  757    bool hasFillAction = 
false;
 
  760        hasFillAction = 
true;
 
 
  774    bool needResize = action->getBufferWidth() > -1 &&
 
  775                      action->getBufferHeight() > -1;
 
  777    if(action->resizeFirst() && needResize) {
 
  778      resizeBuffer(action->getBufferWidth(), action->getBufferHeight());
 
  781    shiftBuffer(action->getXTranslation(), action->getYTranslation());
 
  783    if(!action->resizeFirst() && needResize) {
 
  784      resizeBuffer(action->getBufferWidth(), action->getBufferHeight());
 
 
  800    if(action->started())
 
  803    action->started(
true);
 
  807    if(action->shouldRequestMore()) {
 
 
  836    for(
unsigned int i = 0; i < 
p_buffer.size(); i++) {
 
 
  851      for(
int i = 
p_buffer.size() - 1; i >= deltaY; i--) {
 
  856          for(
unsigned int x = 0; x < 
p_buffer[i - deltaY].size(); x++) {
 
  862          for(
int j = 
p_buffer[i].size() - 1; j >= deltaX; j--) {
 
  867        else if(deltaX < 0) {
 
  868          for(
int j = 0; j < (int)
p_buffer[i].size() + deltaX; j++) {
 
  875    else if(deltaY < 0) {
 
  876      for(
int i = 0; i < (int)
p_buffer.size() + deltaY; i++) {
 
  880        for(
unsigned int x = 0; x < 
p_buffer[i - deltaY].size(); x++) {
 
  885          for(
int j = 
p_buffer[i].size() - 1; j >= deltaX; j--) {
 
  890        else if(deltaX < 0) {
 
  891          for(
int j = 0; j < (int)
p_buffer[i].size() + deltaX; j++) {
 
 
  925    int deltaLeftPixels = (int)round(deltaLeftSamples * 
p_viewport->
scale());
 
  929    int deltaRightPixels = (int)round(deltaRightSamples * 
p_viewport->
scale());
 
  933    int deltaTopPixels = (int)round(deltaTopSamples * 
p_viewport->
scale());
 
  937    int deltaBottomPixels = (int)round(deltaBottomSamples *
 
  941    int deltaW = - deltaLeftPixels + deltaRightPixels;
 
  944    int deltaH = - deltaTopPixels + deltaBottomPixels;
 
  966        QRect leftRect(topLeftOfLeftRect, bottomRightOfLeftRect);
 
  979        QRect rightRect(topLeftOfRightRect, bottomRightOfRightRect);
 
  986      else if(deltaW < 0) {
 
 1018        QRect bottomSideToFill(topLeftOfbottomSide,
 
 1030      else if(deltaH < 0) {
 
 
 1070    int deltaLeftPixels = (int)round(deltaLeftSamples * 
p_viewport->
scale());
 
 1102        QRect fillArea(topLeftOfRefill, bottomRightOfRefill);
 
 1108      else if(deltaX < 0) {
 
 1125          QRect refillArea(topLeftOfRefill, bottomRightOfRefill);
 
 1148        QRect fillArea(topLeftOfFillArea, bottomRightOfFillArea);
 
 1170        QRect fillArea(topLeftOfFillArea, bottomRightOfFillArea);
 
 1175      else if(deltaY < 0) {
 
 1190          QRect fillArea(topLeftOfFillArea, bottomRightOfFillArea);
 
 1209        QRect fillArea(topLeftOfFillArea, bottomRightOfFillArea);
 
 
 1225    for(
int i = 0; i < 
p_actions->size(); i++) {
 
 
 1264    if(!rect.height() || !
p_buffer.size())
 
 1267    if(rect.height() > (
int) 
p_buffer.size())
 
 1268      rect.setBottom(rect.top() + 
p_buffer.size() - 1);
 
 1270    if(rect.width() > (
int) 
p_buffer[0].size())
 
 1271      rect.setRight(rect.left() + 
p_buffer[0].size() - 1);
 
 
 1354        for(
int i = 
p_actions->size() - 1; i > 0; i--) {
 
 1355          delete(*p_actions)[i];
 
 1360        if(curAction->started()) {
 
 1397                       "Unable to resize and fill buffer.",
 
 
Buffer for containing a three dimensional section of an image.
 
int size() const
Returns the total number of pixels in the shape buffer.
 
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
 
int LineDimension() const
Returns the number of lines in the shape buffer.
 
int SampleDimension() const
Returns the number of samples in the shape buffer.
 
double at(const int index) const
Returns the value in the shape buffer at the given index.
 
int Index(const int i_samp, const int i_line, const int i_band) const
Given a sample, line, and band position, this returns the appropriate index in the shape buffer.
 
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
 
Encapsulation of Cube I/O with Change Notifications.
 
Widget to display Isis cubes for qt apps.
 
int cubeLines() const
Return the number of lines in the cube.
 
virtual void restretch(ViewportBuffer *buffer)=0
This is called by internal viewport buffers when a stretch action should be performed.
 
int cubeSamples() const
Return the number of samples in the cube.
 
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
 
void cubeToViewport(double sample, double line, int &x, int &y) const
Turns a cube into a viewport.
 
void enableProgress()
This restarts the progress bar.
 
void bufferUpdated(QRect rect)
This method is called by ViewportBuffer upon successful completion of all operations and gives the ap...
 
@ Programmer
This error is for when a programmer made an API call that was illegal.
 
Adds specific functionality to C++ strings.
 
@ fill
ViewportBufferFill.
 
@ transform
ViewportBufferTransform.
 
@ stretch
ViewportBufferStretch.
 
double viewportToLine(int y)
Converts screen y position to cube line position.
 
int getRequestPosition() const
Returns the current request position (>= read position)
 
int getTopmostPixelPosition()
Returns the top of the X/Y bounding rect for this fill.
 
int getLeftmostPixelPosition()
Returns the left of the X/Y bounding rect for this fill.
 
void incRequestPosition()
Increment request position.
 
void stop()
Cancels the current operation.
 
void incReadPosition()
Increment read position.
 
int getReadPosition() const
Returns the current read position.
 
QRect * getRect()
Returns the rect that this action is filling in screen pixels.
 
bool shouldRequestMore()
Returns true if request position is past the end of the fill.
 
bool doneReading()
Returns true if read position is past the end of the fill.
 
double viewportToSample(int x)
Converts screen x position to cube sample position.
 
QList< double > p_sampLineBoundingRect
This rect is in cube pixels and represents the area that this viewport buffer defines in the viewport...
 
void enqueueAction(ViewportBufferAction *)
This enqueues the given action.
 
void addStretchAction()
When all current operations finish the cube viewport will be asked to do a stretch if you call this.
 
bool actionsPreserveData()
This returns true if any data currently in the buffer would be preserved if all of the queued actions...
 
void startFillAction(ViewportBufferFill *action)
Initializes a fill action by requesting the initial cube data.
 
void DoneWithData(int, const Isis::Brick *)
Tell cube data thread we're done with a brick.
 
int p_vertScrollBarPos
Current vertical scroll bar position.
 
CubeViewport * p_viewport
The CubeViewport which created this buffer.
 
const std::vector< double > & getLine(int line)
Retrieves a line from the buffer.
 
QRect p_oldXYBoundingRect
The previous bounding rect.
 
QRect getXYBoundingRect()
Retrieves the current bounding rect in viewport pixels of the visible cube area.
 
int p_band
The band to read from.
 
void reinitialize()
This resizes and fills entire buffer.
 
void DataReady(void *requester, int cubeId, const Isis::Brick *brick)
This method is called when requested bricks become available.
 
double totalUnfilledArea()
This returns the amount of area in the queue that needs new cube data/will be filled by fill actions.
 
void resizeBuffer(unsigned int width, unsigned int height)
Enlarges or shrinks the buffer and fills with nulls if necessary.
 
void setBand(int band)
Sets the band to read from, the buffer will be re-read if the band changes.
 
double currentProgress()
Returns the viewport buffer's loading progress.
 
void shiftBuffer(int deltaX, int deltaY)
Shifts the DN values in the buffer by deltaX and deltaY.
 
void ReadCube(int cubeId, int startSample, int startLine, int endSample, int endLine, int band, void *caller)
Ask the cube data thread for data.
 
void doQueuedActions()
This processes the next available action, or starts processing it, if possible.
 
void updateBoundingRects()
Sets the old and new bounding rects.
 
double p_requestedFillArea
Sum of the requested area to be filled.
 
virtual ~ViewportBuffer()
Updates total buffer size on destruction.
 
QQueue< ViewportBufferAction * > * p_actions
This is the set of actions we wish to perform on the buffer.
 
@ rectBottom
QRect.bottom()
 
ViewportBufferFill * createViewportBufferFill(QRect, bool)
This method creates a fill action based on a rect and using new versus old Y values.
 
int p_oldViewportHeight
Previous viewport height.
 
bool p_initialStretchDone
True if a stretch action has occurred.
 
ViewportBuffer(CubeViewport *viewport, CubeDataThread *cubeData, int cubeId)
ViewportBuffer constructor.
 
void enable(bool enabled)
This turns on or off reading from the cube.
 
void doStretchAction(ViewportBufferStretch *action)
Tells the cube viewport to restretch.
 
QList< double > p_oldSampLineBoundingRect
Previous bounding rect.
 
QList< double > getSampLineBoundingRect()
Retrieves the current bounding rect in sample/line coordinates of the visible cube area.
 
QRect bufferXYRect()
Returns a rect, in screen pixels, of the area this buffer covers.
 
bool p_bufferInitialized
True if the buffer has been initialized.
 
void resizedViewport()
Call this when the viewport is resized (not zoomed).
 
bool enabled()
Returns whether the buffer is enabled (reading data) or not.
 
CubeDataThread * p_dataThread
manages cube io
 
int p_cubeId
Id associated with the cube in this viewport buffer.
 
int p_oldVertScrollBarPos
Previous vertical scroll bar position.
 
bool hasEntireCube()
Method to see if the entire cube is in the buffer.
 
QRect p_XYBoundingRect
This rect is in viewport pixels and represents the area that this viewport buffer defines in the view...
 
void fillBuffer(QRect rect)
This method will convert the rect to sample/line positions and read from the cube into the buffer.
 
void emptyBuffer(bool force=false)
This is meant to clear up ram on non-active viewports.
 
void doTransformAction(ViewportBufferTransform *action)
Does a transformation on the internal viewport buffer.
 
bool working()
This tests if queued actions exist in the viewport buffer.
 
bool p_enabled
True if reading from cube (active)
 
void pan(int deltaX, int deltaY)
Call this when the viewport is panned.
 
std::vector< std::vector< double > > p_buffer
The buffer to hold cube dn values.
 
void scaleChanged()
Call this when zoomed, re-reads visible area.
 
void requestCubeLine(ViewportBufferFill *fill)
This requests the next line in a fill action.
 
int p_viewportHeight
Current viewport height.
 
bool reinitializeActionExists()
This searches for actions that will reset the entire buffer's contents.
 
This is free and unencumbered software released into the public domain.
 
const double Null
Value for an Isis Null pixel.
 
Namespace for the standard library.