vector<GLubyte> Texture<GLubyte>::loadPNG(istream &input, NormalizedFormat &format, uint &width, uint &height) { png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if(!pngPtr) throw log(__FILE__, __LINE__, LogType::error, "Failed to load " + d_filename); png_infop infoPtr = png_create_info_struct(pngPtr); if(!infoPtr) throw log(__FILE__, __LINE__, LogType::error, "Failed to load " + d_filename); if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to load " + d_filename); png_set_read_fn(pngPtr, reinterpret_cast<png_voidp>(&input), readFromStream); png_set_sig_bytes(pngPtr, 8); png_read_info(pngPtr, infoPtr); width = png_get_image_width(pngPtr, infoPtr); height = png_get_image_height(pngPtr, infoPtr); png_uint_32 color = png_get_color_type(pngPtr, infoPtr); png_uint_32 channels = png_get_channels(pngPtr, infoPtr); png_uint_32 depth = png_get_bit_depth(pngPtr, infoPtr); switch (color) { case PNG_COLOR_TYPE_GRAY: if (depth < 8) png_set_expand_gray_1_2_4_to_8(pngPtr); depth = 8; format = NormalizedFormat::R8; break; case PNG_COLOR_TYPE_GRAY_ALPHA: format = NormalizedFormat::RG8; break; case PNG_COLOR_TYPE_PALETTE: png_set_palette_to_rgb(pngPtr); channels = 3; case PNG_COLOR_TYPE_RGB: format = NormalizedFormat::RGB8; break; case PNG_COLOR_TYPE_RGB_ALPHA: format = NormalizedFormat::RGBA8; break; } if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(pngPtr); channels+=1; } if(depth == 16) { png_set_strip_16(pngPtr); depth = 8; } else if(depth < 8) { png_set_packing(pngPtr); depth = 8; } /* read file */ if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to load " + d_filename); vector<png_bytep> rowPtrs(height); vector<GLubyte> data(height * width * channels); for(uint y = 0; y != height; ++y) { png_uint_32 offset = y * (width * channels); rowPtrs.at(y) = static_cast<png_bytep>(data.data()) + offset; } png_read_image(pngPtr, rowPtrs.data()); png_destroy_read_struct(&pngPtr, &infoPtr, 0); return data; }
void NCL2MT::processTree(std::ostream *os, unsigned numTaxa, const NxsCharactersBlock * charsBlock, const NxsDiscreteDatatypeMapper * dataMapper, const NxsCDiscreteStateSet ** compressedMatrix, const vector<double> & patternWeights, const vector<int> &origToCompressed, const NxsSimpleTree & nxsTree, const ModelDescription & md, ::INIReader & iniReader) { assert(dataMapper != nullptr); const unsigned numRealChars = patternWeights.size(); unsigned firstPartLength = patternWeights.size(); const unsigned numStates = dataMapper->GetNumStates(); vector<unsigned> origToComp; for (auto otc : origToCompressed) { origToComp.push_back((unsigned) otc); } vector<mt::char_state_t> bogusChar; if (md.GetAscBiasMode() == mt::ModelDescription::VAR_ONLY_NO_MISSING_ASC_BIAS) { firstPartLength += numStates; for (auto i = 0U; i < numStates; ++i) { bogusChar.push_back(i); } } vector<vector<mt::char_state_t> > rawMatrix(numTaxa); NxsCDiscreteStateSet maxStateCode = 0; for (auto i = 0U; i < numTaxa; ++i) { rawMatrix[i].reserve(firstPartLength); for (auto j = 0U; j < numRealChars; ++j) { NxsCDiscreteStateSet r = compressedMatrix[i][j]; if (r < 0) { r = numStates; } if (r > maxStateCode) { maxStateCode = r; } rawMatrix[i].push_back((mt::char_state_t) compressedMatrix[i][j]); } for (auto k : bogusChar) { rawMatrix[i].push_back(k); } } vector<mt::char_state_t *> rowPtrs(numTaxa); for (auto i = 0U; i < numTaxa; ++i) { rowPtrs[i] = &(rawMatrix[i][0]); } if (maxStateCode < (NxsCDiscreteStateSet) numStates) { maxStateCode = numStates; } unsigned numStateCodes = maxStateCode + 1; mt::CharStateToPrimitiveInd cs2pi(numStateCodes); for (auto i = 0U; i < numStateCodes; ++i) { vector<mt::char_state_t> v; for (auto xs : dataMapper->GetStateSetForCode(i)) { v.push_back(static_cast<mt::char_state_t>(xs)); } cs2pi.SetStateCode(i, v); } std::vector<unsigned> partLengths(1, firstPartLength); mt::CharModel * cm; unsigned numRateCats = 1; if (md.GetAscBiasMode() == mt::ModelDescription::VAR_ONLY_NO_MISSING_ASC_BIAS) { cm = new mt::MkVarNoMissingAscCharModel(numStates, numRateCats); } else { cm = new mt::MkCharModel(numStates, numRateCats); } unsigned numNodes = 2 * numTaxa - 1; BitFieldMatrix bMat; cm->alphabet = convertToBitFieldMatrix(*charsBlock, bMat); mt::MTInstance mtInstance(numTaxa, partLengths, origToComp, patternWeights, cm); mt::PartitionedMatrix & partMat = mtInstance.partMat; partMat.fillPartition(0, const_cast<const mt::char_state_t**>(&(rowPtrs[0])), &cs2pi); mt::Tree &tree = mtInstance.tree; std::map<const NxsSimpleNode *, unsigned> ncl2nodeNumber; std::vector<const NxsSimpleNode *> pre = nxsTree.GetPreorderTraversal(); unsigned internalIndex = numTaxa; for (std::vector<const NxsSimpleNode *>::iterator ndIt = pre.begin(); ndIt != pre.end(); ++ndIt) { const NxsSimpleNode *nd = *ndIt; //std::cout << "address = " << (long) nd << " is leaf = " << nd->IsTip() << " index = " << nd->GetTaxonIndex() << " parent address = " << (long) nd->GetEdgeToParent().GetParent() << std::endl; unsigned num; if (nd->IsTip()) { num = nd->GetTaxonIndex(); } else { num = internalIndex++; } mt::Node * treeNode = tree.GetNode(num); const NxsSimpleNode * par = nd->GetEdgeToParent().GetParent(); if (par == nullptr) { tree.SetRoot(treeNode); } else { assert (ncl2nodeNumber.find(par) != ncl2nodeNumber.end()); unsigned parNodeNumber = ncl2nodeNumber[par]; mt::Node * parNode = tree.GetNode(parNodeNumber); parNode->AddChild(treeNode, nd->GetEdgeToParent().GetDblEdgeLen()); } ncl2nodeNumber[nd] = num; } for (auto li = 0U; li < numTaxa; ++li) { mt::Node * leaf = tree.GetLeaf(li); assert(leaf); for (auto j = 0U; j < partMat.GetNumPartitions(); ++j) { leaf->SetData(j, (void *) partMat.GetLeafCharacters(j, li)); leaf->SetWork(j, (void *) new mt::LeafWork(firstPartLength, numStateCodes, numStates, numRateCats)); } } for (auto li = numTaxa; li < numNodes; ++ li) { mt::Node * nd = tree.GetNode(li); for (auto j = 0U; j < partMat.GetNumPartitions(); ++j) { nd->SetWork(j, (void *) new mt::InternalNodeWork(firstPartLength, numStates, numRateCats)); } } mt::ProcessActionsEnum action = configureBasedOnINI(mtInstance, iniReader, std::cerr); try { doAnalysis(os, mtInstance, action); } catch (...) { delete cm; throw; } delete cm; }
void Texture<GLubyte>::savePNG(string const &filename, ostream &output, vector<GLubyte> const &data) const { png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if(!pngPtr) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); png_infop infoPtr = png_create_info_struct(pngPtr); if(!infoPtr) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); png_set_write_fn(pngPtr, reinterpret_cast<png_voidp>(&output), writeToStream, flushStream); if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); png_uint_32 color = PNG_COLOR_TYPE_GRAY; uint channels = 1; switch(externalFormat()) { case GL_RED: color = PNG_COLOR_TYPE_GRAY; channels = 1; break; case GL_RG: color = PNG_COLOR_TYPE_GRAY_ALPHA; channels = 2; break; case GL_RGB: color = PNG_COLOR_TYPE_RGB; channels = 3; break; case GL_RGBA: color = PNG_COLOR_TYPE_RGB_ALPHA; channels = 4; break; default: throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); } png_set_IHDR(pngPtr, infoPtr, width(), height(), 8, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(pngPtr, infoPtr); vector<png_bytep> rowPtrs(height()); for(uint y = 0; y != height(); ++y) { // A const_cast is used because libpng won't take anything else png_uint_32 offset = y * (width() * channels); rowPtrs.at(y) = static_cast<png_bytep>(const_cast<GLubyte*>(data.data())) + offset; } if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); png_write_image(pngPtr, rowPtrs.data()); if(setjmp(png_jmpbuf(pngPtr))) throw log(__FILE__, __LINE__, LogType::error, "Failed to save " + filename); png_write_end(pngPtr, 0); png_destroy_write_struct(&pngPtr, &infoPtr); }