📄 imfoutputfile.cpp
字号:
_ofd (ofd), _lineBuffer (_ofd->getLineBuffer(number)){ // // Wait for the lineBuffer to become available // _lineBuffer->wait (); // // Initialize the lineBuffer data if necessary // if (!_lineBuffer->partiallyFull) { _lineBuffer->endOfLineBufferData = _lineBuffer->buffer; _lineBuffer->minY = _ofd->minY + number * _ofd->linesInBuffer; _lineBuffer->maxY = min (_lineBuffer->minY + _ofd->linesInBuffer - 1, _ofd->maxY); _lineBuffer->partiallyFull = true; } _lineBuffer->scanLineMin = max (_lineBuffer->minY, scanLineMin); _lineBuffer->scanLineMax = min (_lineBuffer->maxY, scanLineMax);}LineBufferTask::~LineBufferTask (){ // // Signal that the line buffer is now free // _lineBuffer->post ();}voidLineBufferTask::execute (){ try { // // First copy the pixel data from the // frame buffer into the line buffer // int yStart, yStop, dy; if (_ofd->lineOrder == INCREASING_Y) { yStart = _lineBuffer->scanLineMin; yStop = _lineBuffer->scanLineMax + 1; dy = 1; } else { yStart = _lineBuffer->scanLineMax; yStop = _lineBuffer->scanLineMin - 1; dy = -1; } int y; for (y = yStart; y != yStop; y += dy) { // // Gather one scan line's worth of pixel data and store // them in _ofd->lineBuffer. // char *writePtr = _lineBuffer->buffer + _ofd->offsetInLineBuffer[y - _ofd->minY]; // // Iterate over all image channels. // for (unsigned int i = 0; i < _ofd->slices.size(); ++i) { // // Test if scan line y of this channel contains any data // (the scan line contains data only if y % ySampling == 0). // const OutSliceInfo &slice = _ofd->slices[i]; if (modp (y, slice.ySampling) != 0) continue; // // Find the x coordinates of the leftmost and rightmost // sampled pixels (i.e. pixels within the data window // for which x % xSampling == 0). // int dMinX = divp (_ofd->minX, slice.xSampling); int dMaxX = divp (_ofd->maxX, slice.xSampling); // // Fill the line buffer with with pixel data. // if (slice.zero) { // // The frame buffer contains no data for this channel. // Store zeroes in _lineBuffer->buffer. // fillChannelWithZeroes (writePtr, _ofd->format, slice.type, dMaxX - dMinX + 1); } else { // // If necessary, convert the pixel data to Xdr format. // Then store the pixel data in _ofd->lineBuffer. // const char *linePtr = slice.base + divp (y, slice.ySampling) * slice.yStride; const char *readPtr = linePtr + dMinX * slice.xStride; const char *endPtr = linePtr + dMaxX * slice.xStride; copyFromFrameBuffer (writePtr, readPtr, endPtr, slice.xStride, _ofd->format, slice.type); } } if (_lineBuffer->endOfLineBufferData < writePtr) _lineBuffer->endOfLineBufferData = writePtr; #ifdef DEBUG assert (writePtr - (_lineBuffer->buffer + _ofd->offsetInLineBuffer[y - _ofd->minY]) == (int) _ofd->bytesPerLine[y - _ofd->minY]); #endif } // // If the next scanline isn't past the bounds of the lineBuffer // then we are done, otherwise compress the linebuffer // if (y >= _lineBuffer->minY && y <= _lineBuffer->maxY) return; _lineBuffer->dataPtr = _lineBuffer->buffer; _lineBuffer->dataSize = _lineBuffer->endOfLineBufferData - _lineBuffer->buffer; // // Compress the data // Compressor *compressor = _lineBuffer->compressor; if (compressor) { const char *compPtr; int compSize = compressor->compress (_lineBuffer->dataPtr, _lineBuffer->dataSize, _lineBuffer->minY, compPtr); if (compSize < _lineBuffer->dataSize) { _lineBuffer->dataSize = compSize; _lineBuffer->dataPtr = compPtr; } else if (_ofd->format == Compressor::NATIVE) { // // The data did not shrink during compression, but // we cannot write to the file using the machine's // native format, so we need to convert the lineBuffer // to Xdr. // convertToXdr (_ofd, _lineBuffer->buffer, _lineBuffer->minY, _lineBuffer->maxY, _lineBuffer->dataSize); } } _lineBuffer->partiallyFull = false; } catch (std::exception &e) { if (!_lineBuffer->hasException) { _lineBuffer->exception = e.what (); _lineBuffer->hasException = true; } } catch (...) { if (!_lineBuffer->hasException) { _lineBuffer->exception = "unrecognized exception"; _lineBuffer->hasException = true; } }}} // namespaceOutputFile::OutputFile (const char fileName[], const Header &header, int numThreads): _data (new Data (true, numThreads)){ try { header.sanityCheck(); _data->os = new StdOFStream (fileName); initialize (header); } catch (Iex::BaseExc &e) { delete _data; REPLACE_EXC (e, "Cannot open image file " "\"" << fileName << "\". " << e); throw; } catch (...) { delete _data; throw; }}OutputFile::OutputFile (OStream &os, const Header &header, int numThreads): _data (new Data (false, numThreads)){ try { header.sanityCheck(); _data->os = &os; initialize (header); } catch (Iex::BaseExc &e) { delete _data; REPLACE_EXC (e, "Cannot open image file " "\"" << os.fileName() << "\". " << e); throw; } catch (...) { delete _data; throw; }}voidOutputFile::initialize (const Header &header){ _data->header = header; const Box2i &dataWindow = header.dataWindow(); _data->currentScanLine = (header.lineOrder() == INCREASING_Y)? dataWindow.min.y: dataWindow.max.y; _data->missingScanLines = dataWindow.max.y - dataWindow.min.y + 1; _data->lineOrder = header.lineOrder(); _data->minX = dataWindow.min.x; _data->maxX = dataWindow.max.x; _data->minY = dataWindow.min.y; _data->maxY = dataWindow.max.y; size_t maxBytesPerLine = bytesPerLineTable (_data->header, _data->bytesPerLine); for (size_t i = 0; i < _data->lineBuffers.size(); ++i) { _data->lineBuffers[i] = new LineBuffer (newCompressor (_data->header.compression(), maxBytesPerLine, _data->header)); } LineBuffer *lineBuffer = _data->lineBuffers[0]; _data->format = defaultFormat (lineBuffer->compressor); _data->linesInBuffer = numLinesInBuffer (lineBuffer->compressor); _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer; for (size_t i = 0; i < _data->lineBuffers.size(); i++) _data->lineBuffers[i]->buffer.resizeErase(_data->lineBufferSize); int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y + _data->linesInBuffer) / _data->linesInBuffer; _data->lineOffsets.resize (lineOffsetSize); offsetInLineBufferTable (_data->bytesPerLine, _data->linesInBuffer, _data->offsetInLineBuffer); _data->previewPosition = _data->header.writeTo (*_data->os); _data->lineOffsetsPosition = writeLineOffsets (*_data->os, _data->lineOffsets); _data->currentPosition = _data->os->tellp();}OutputFile::~OutputFile (){ if (_data) { { if (_data->lineOffsetsPosition > 0) { try { _data->os->seekp (_data->lineOffsetsPosition); writeLineOffsets (*_data->os, _data->lineOffsets); } catch (...) { // // We cannot safely throw any exceptions from here. // This destructor may have been called because the // stack is currently being unwound for another // exception. // } } } delete _data; }}const char *OutputFile::fileName () const{ return _data->os->fileName();}const Header &OutputFile::header () const{ return _data->header;}void OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer){ Lock lock (*_data); // // Check if the new frame buffer descriptor // is compatible with the image file header. // const ChannelList &channels = _data->header.channels(); for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) continue; if (i.channel().type != j.slice().type) { THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel " "of output file \"" << fileName() << "\" is " "not compatible with the frame buffer's " "pixel type."); } if (i.channel().xSampling != j.slice().xSampling || i.channel().ySampling != j.slice().ySampling) { THROW (Iex::ArgExc, "X and/or y subsampling factors " "of \"" << i.name() << "\" channel " "of output file \"" << fileName() << "\" are " "not compatible with the frame buffer's " "subsampling factors."); } } // // Initialize slice table for writePixels(). // vector<OutSliceInfo> slices; for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) { // // Channel i is not present in the frame buffer. // In the file, channel i will contain only zeroes.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -