bool StringTableFromExcelXML(Data::PXMLDocument Doc,
							 Data::CTTable<nString>& Out,
							 LPCSTR pWorksheetName,
							 bool FirstRowAsColNames,
							 bool FirstColAsRowNames)
{
	if (!Doc.isvalid() || Doc->Error()) FAIL;

	tinyxml2::XMLHandle hDoc(Doc);
	tinyxml2::XMLElement* pSheet = hDoc.FirstChildElement("Workbook").FirstChildElement("Worksheet").ToElement();

	if (pWorksheetName && *pWorksheetName)
		for (; pSheet; pSheet = pSheet->NextSiblingElement("Worksheet"))
			if (!strcmp(pWorksheetName, pSheet->Attribute("ss:Name"))) break;

	if (!pSheet) FAIL;

	tinyxml2::XMLElement* pTable = pSheet->FirstChildElement("Table");
	n_assert(pTable);

	nString CellText;

	Out.Name = pSheet->Attribute("ss:Name");
	Out.ColMap.Clear();
	Out.RowMap.Clear();

	// Count columns and optionally save column name to index mapping
	DWORD ColCount = 0;
	DWORD TableW = 0;
	tinyxml2::XMLHandle hTable(pTable);
	tinyxml2::XMLElement* pCell = hTable.FirstChildElement("Row").FirstChildElement("Cell").ToElement();
	
	if (FirstColAsRowNames)
	{
		pCell = pCell->NextSiblingElement("Cell");
		++ColCount;
	}
	
	for (; pCell; pCell = pCell->NextSiblingElement("Cell"))
	{
		if (pCell->FirstChildElement("Data"))
		{
			if (FirstRowAsColNames)
			{
				GetTextFromCell(pCell, CellText);
				if (CellText.IsValid()) Out.ColMap.Add(CStrID(CellText.Get()), TableW);
			}
			++ColCount;
			++TableW;
		}
	}

	// Count rows
	DWORD RowCount = 0;
	tinyxml2::XMLElement* pRow = pTable->FirstChildElement("Row");

	if (FirstRowAsColNames)
	{
		pRow = pRow->NextSiblingElement("Row");
		++RowCount;
	}

	for (; pRow; pRow = pRow->NextSiblingElement("Row"))
	{
		tinyxml2::XMLHandle hRow(pRow);
		if (hRow.FirstChildElement("Cell").FirstChildElement("Data").ToElement()) ++RowCount;
		else break;
	}

	DWORD TableH = FirstRowAsColNames ? RowCount - 1 : RowCount;

	if (!ColCount || !RowCount || !TableW || !TableH)
	{
		Out.SetSize(0, 0);
		OK;
	}

	Out.SetSize(TableW, TableH);

	pRow = pTable->FirstChildElement("Row");
	if (FirstRowAsColNames) pRow = pRow->NextSiblingElement("Row");

	for (DWORD CurrRow = 0; pRow && (CurrRow < TableH); ++CurrRow, pRow = pRow->NextSiblingElement("Row"))
	{
		tinyxml2::XMLElement* pCell = pRow->FirstChildElement("Cell");

		DWORD CurrCol = 0;
		if (FirstColAsRowNames)
		{
			GetTextFromCell(pCell, CellText);
			if (CellText.IsValid()) Out.RowMap.Add(CStrID(CellText.Get()), CurrRow);
			pCell = pCell->NextSiblingElement("Cell");
			++CurrCol;
		}

		for (; pCell && (CurrCol < TableW); ++CurrCol, pCell = pCell->NextSiblingElement("Cell"))
		{
			// Check if cells are skipped
			int CellIdx;
			if (pCell->QueryIntAttribute("ss:Index", &CellIdx) == tinyxml2::XML_SUCCESS)
				CurrCol = CellIdx - 1;

			GetTextFromCell(pCell, CellText);
			Out.Set(FirstColAsRowNames ? CurrCol - 1 : CurrCol, CurrRow, CellText);
		}
	}

	OK;
}
Exemplo n.º 2
0
void savePng(GImage* pImage, FILE* pFile, bool bIncludeAlphaChannel)
{
	// Set the jump value (This has something to do with enabling the error handler)
	GPNGWriter writer;
	if(setjmp(png_jmpbuf(writer.m_pWriteStruct)))
		throw Ex("Failed to set the jump value");

	// Init the IO
	png_init_io(writer.m_pWriteStruct, pFile);
	png_set_compression_level(writer.m_pWriteStruct, Z_BEST_COMPRESSION);

	// Write image stats and settings
	unsigned long width = pImage->width();
	unsigned long height = pImage->height();
	png_set_IHDR(writer.m_pWriteStruct, writer.m_pInfoStruct,
		width, height, 8,
		bIncludeAlphaChannel ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
		PNG_INTERLACE_NONE,	PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
	png_write_info(writer.m_pWriteStruct, writer.m_pInfoStruct);
	png_set_packing(writer.m_pWriteStruct);

	// Write the image data
	unsigned long channels = bIncludeAlphaChannel ? 4 : 3;
	unsigned long rowbytes = width * channels;
	unsigned char* pRow = new unsigned char[rowbytes];
	ArrayHolder<unsigned char> hRow(pRow);
	unsigned int* pPix = pImage->pixels();
	if(channels == 4)
	{
		for(unsigned int i = 0; i < height; i++)
		{
			unsigned char* pBytes = pRow;
			for(unsigned int j = 0; j < width; j++)
			{
				*(pBytes++) = gRed(*pPix);
				*(pBytes++) = gGreen(*pPix);
				*(pBytes++) = gBlue(*pPix);
				*(pBytes++) = gAlpha(*pPix);
				pPix++;
			}
			png_write_row(writer.m_pWriteStruct, pRow);
		}
	}
	else if(channels == 3)
	{
		for(unsigned int i = 0; i < height; i++)
		{
			unsigned char* pBytes = pRow;
			for(unsigned int j = 0; j < width; j++)
			{
				*(pBytes++) = gRed(*pPix);
				*(pBytes++) = gGreen(*pPix);
				*(pBytes++) = gBlue(*pPix);
			}
			png_write_row(writer.m_pWriteStruct, pRow);
		}
	}
	else
		throw Ex("Unsupported number of channels");
	png_write_end(writer.m_pWriteStruct, writer.m_pInfoStruct);
}