Beispiel #1
0
int vtUnzip::Extract(bool bFullPath, bool bOverwrite, const char *lpszDst,
					 bool progress_callback(int))
{
	int iCount = 0;
	int iTotal = GetGlobalCount();

	bool bOK = true;
	for (bool bContinue = GoToFirstFile(); bContinue; bContinue = GoToNextFile())
	{
		char szFileName[MAX_PATH];
		unz_file_info info;
		bOK = GetCurrentFileInfo(&info, szFileName, MAX_PATH);
		if (!bOK)
			break;

		vtString src_filename = szFileName;

		const char *short_fname = (const char *)src_filename;
		for (const char *p = short_fname;
			(*p) != '\0';
			p++)
		{
			if (((*p)=='/') || ((*p)=='\\'))
			{
				short_fname = p+1;
			}
		}
		vtString short_filename = short_fname;

		if ((*short_filename)=='\0')
		{
			if (bFullPath)
			{
				VTLOG("creating directory: %s\n", (const char *)src_filename);
				vtCreateDir(src_filename);
			}
		}
		else
		{
			bOK = OpenCurrentFile();
			if (bOK)
			{
				vtString write_filename;
				write_filename = vtString(lpszDst) + (bFullPath ? src_filename : short_filename);

				vtString strResult;

				VTLOG("Extracting %s ...", (const char *) write_filename);
				if (ExtractAccept(write_filename, bOverwrite))
				{
					FILE* file = vtFileOpen(write_filename, "wb");

					bool bWrite = (file != NULL);
					if (bWrite)
					{
						char buf[4096];
						bWrite = ExtractCurrentFile(file, buf, 4096);
						fclose(file);
					}
					if (bWrite)
					{
						vtUnzip::change_file_date(write_filename,info.dosDate, info.tmu_date);
						iCount++;
						if (progress_callback != NULL)
						{
							progress_callback(iCount * 99 / iTotal);
						}
					}
					else
					{
						m_error_count++;
						OnError(write_filename);
					}
					strResult = bWrite ? "ok" : "failed";
				}
				else
				{
					strResult = "skipped";
				}
				VTLOG(" %s\n", (const char *) strResult);
				CloseCurrentFile();
			}
		}
	}
	if (bOK)
		return iCount;
	else
		return -1;
}
Beispiel #2
0
bool vtElevLayer::WriteElevationTileset(TilingOptions &opts, BuilderView *pView)
{
	// Avoid trouble with '.' and ',' in Europe
	ScopedLocale normal_numbers(LC_NUMERIC, "C");

	// Check that options are valid
	CheckCompressionMethod(opts);

	// grid size
	int base_tilesize = opts.lod0size;

	int gridcols, gridrows;
	m_pGrid->GetDimensions(gridcols, gridrows);

	DRECT area = m_pGrid->GetEarthExtents();
	DPoint2 tile_dim(area.Width()/opts.cols, area.Height()/opts.rows);
	DPoint2 cell_size = tile_dim / base_tilesize;

	const vtProjection &proj = m_pGrid->GetProjection();
	vtString units = GetLinearUnitName(proj.GetUnits());
	units.MakeLower();
	int zone = proj.GetUTMZone();
	vtString crs;
	if (proj.IsGeographic())
		crs = "LL";
	else if (zone != 0)
		crs = "UTM";
	else
		crs = "Other";

	// Try to create directory to hold the tiles
	vtString dirname = opts.fname;
	RemoveFileExtensions(dirname);
	if (!vtCreateDir(dirname))
		return false;

	// We won't know the exact height extents until the tiles have generated,
	//  so gather extents as we produce the tiles and write the INI later.
	float minheight = 1E9, maxheight = -1E9;

	ColorMap cmap;
	vtElevLayer::SetupDefaultColors(cmap);	// defaults
	vtString dirname_image = opts.fname_images;
	RemoveFileExtensions(dirname_image);
	if (opts.bCreateDerivedImages)
	{
		if (!vtCreateDir(dirname_image))
			return false;

		vtString cmap_fname = opts.draw.m_strColorMapFile;
		vtString cmap_path = FindFileOnPaths(vtGetDataPath(), "GeoTypical/" + cmap_fname);
		if (cmap_path == "")
			DisplayAndLog("Couldn't find color map.");
		else
		{
			if (!cmap.Load(cmap_path))
				DisplayAndLog("Couldn't load color map.");
		}
	}

	ImageGLCanvas *pCanvas = NULL;
#if USE_OPENGL
	wxFrame *frame = new wxFrame;
	if (opts.bCreateDerivedImages && opts.bUseTextureCompression && opts.eCompressionType == TC_OPENGL)
	{
		frame->Create(g_bld->m_pParentWindow, -1, _T("Texture Compression OpenGL Context"),
			wxPoint(100,400), wxSize(280, 300), wxCAPTION | wxCLIP_CHILDREN);
		pCanvas = new ImageGLCanvas(frame);
	}
#endif

	// make a note of which lods exist
	LODMap lod_existence_map(opts.cols, opts.rows);

	bool bFloat = m_pGrid->IsFloatMode();
	bool bJPEG = (opts.bUseTextureCompression && opts.eCompressionType == TC_JPEG);

	int i, j, lod;
	int total = opts.rows * opts.cols, done = 0;
	for (j = 0; j < opts.rows; j++)
	{
		for (i = 0; i < opts.cols; i++)
		{
			// We might want to skip certain tiles
			if (opts.iMinRow != -1 &&
				(i < opts.iMinCol || i > opts.iMaxCol ||
				 j < opts.iMinRow || j > opts.iMaxRow))
				continue;

			DRECT tile_area;
			tile_area.left = area.left + tile_dim.x * i;
			tile_area.right = area.left + tile_dim.x * (i+1);
			tile_area.bottom = area.bottom + tile_dim.y * j;
			tile_area.top = area.bottom + tile_dim.y * (j+1);

			int col = i;
			int row = opts.rows-1-j;

			// draw our progress in the main view
			if (pView)
				pView->ShowGridMarks(area, opts.cols, opts.rows, col, opts.rows-1-row);

			// Extract the highest LOD we need
			vtElevationGrid base_lod(tile_area, IPoint2(base_tilesize+1, base_tilesize+1),
				bFloat, proj);

			bool bAllInvalid = true;
			bool bAllZero = true;
			int iNumInvalid = 0;
			DPoint2 p;
			int x, y;
			for (y = base_tilesize; y >= 0; y--)
			{
				p.y = area.bottom + (j*tile_dim.y) + ((double)y / base_tilesize * tile_dim.y);
				for (x = 0; x <= base_tilesize; x++)
				{
					p.x = area.left + (i*tile_dim.x) + ((double)x / base_tilesize * tile_dim.x);

					float fvalue = m_pGrid->GetFilteredValue(p);
					base_lod.SetFValue(x, y, fvalue);

					if (fvalue == INVALID_ELEVATION)
						iNumInvalid++;
					else
					{
						bAllInvalid = false;

						// Gather height extents
						if (fvalue < minheight)
							minheight = fvalue;
						if (fvalue > maxheight)
							maxheight = fvalue;
					}
					if (fvalue != 0)
						bAllZero = false;
				}
			}
			// Increment whether we omit or not
			done++;

			// If there is no real data there, omit this tile
			if (bAllInvalid)
				continue;

			// Omit all-zero tiles (flat sea-level) if desired
			if (opts.bOmitFlatTiles && bAllZero)
				continue;

			// Now we know this tile will be included, so note the LODs present
			int base_tile_exponent = vt_log2(base_tilesize);
			lod_existence_map.set(i, j, base_tile_exponent, base_tile_exponent-(opts.numlods-1));

			if (iNumInvalid > 0)
			{
				UpdateProgressDialog2(done*99/total, 0, _("Filling gaps"));

				bool bGood;
				int method = g_Options.GetValueInt(TAG_GAP_FILL_METHOD);
				if (method == 1)
					bGood = base_lod.FillGaps(NULL, progress_callback_minor);
				else if (method == 2)
					bGood = base_lod.FillGapsSmooth(NULL, progress_callback_minor);
				else if (method == 3)
					bGood = (base_lod.FillGapsByRegionGrowing(2, 5, progress_callback_minor) != -1);
				if (!bGood)
					return false;

				opts.iNoDataFilled += iNumInvalid;
			}

			// Create a matching derived texture tileset
			if (opts.bCreateDerivedImages)
			{
				// Create a matching derived texture tileset
				vtDIB dib;
				base_lod.ComputeHeightExtents();

				if (opts.bImageAlpha)
				{
					dib.Create(IPoint2(base_tilesize, base_tilesize), 32);
					base_lod.ColorDibFromElevation(&dib, &cmap, 4000, RGBAi(0,0,0,0));
				}
				else
				{
					dib.Create(IPoint2(base_tilesize, base_tilesize), 24);
					base_lod.ColorDibFromElevation(&dib, &cmap, 4000, RGBi(255,0,0));
				}

				if (opts.draw.m_bShadingQuick)
					base_lod.ShadeQuick(&dib, SHADING_BIAS, true);
				else if (opts.draw.m_bShadingDot)
				{
					FPoint3 light_dir = LightDirection(opts.draw.m_iCastAngle,
						opts.draw.m_iCastDirection);

					// Don't cast shadows for tileset; they won't cast
					//  correctly from one tile to the next.
					base_lod.ShadeDibFromElevation(&dib, light_dir, 1.0f,
						opts.draw.m_fAmbient, opts.draw.m_fGamma, true);
				}

				for (int k = 0; k < opts.numlods; k++)
				{
					vtString fname = MakeFilenameDB(dirname_image, col, row, k);

					int tilesize = base_tilesize >> k;

					vtMiniDatabuf output_buf;
					output_buf.xsize = tilesize;
					output_buf.ysize = tilesize;
					output_buf.zsize = 1;
					output_buf.tsteps = 1;
					output_buf.SetBounds(proj, tile_area);

					int depth = dib.GetDepth() / 8;
					int iUncompressedSize = tilesize * tilesize * depth;
					uchar *rgb_bytes = (uchar *) malloc(iUncompressedSize);

					uchar *dst = rgb_bytes;
					if (opts.bImageAlpha)
					{
						RGBAi rgba;
						for (int ro = 0; ro < base_tilesize; ro += (1<<k))
							for (int co = 0; co < base_tilesize; co += (1<<k))
							{
								dib.GetPixel32(co, ro, rgba);
								*dst++ = rgba.r;
								*dst++ = rgba.g;
								*dst++ = rgba.b;
								*dst++ = rgba.a;
							}
					}
					else
					{
						RGBi rgb;
						for (int ro = 0; ro < base_tilesize; ro += (1<<k))
							for (int co = 0; co < base_tilesize; co += (1<<k))
							{
								dib.GetPixel24(co, ro, rgb);
								*dst++ = rgb.r;
								*dst++ = rgb.g;
								*dst++ = rgb.b;
							}
					}

					// Write and optionally compress the image
					WriteMiniImage(fname, opts, rgb_bytes, output_buf,
						iUncompressedSize, pCanvas);

					// Free the uncompressed image
					free(rgb_bytes);
				}
			}

			for (lod = 0; lod < opts.numlods; lod++)
			{
				int tilesize = base_tilesize >> lod;

				vtString fname = MakeFilenameDB(dirname, col, row, lod);

				// make a message for the progress dialog
				wxString msg;
				msg.Printf(_("Writing tile '%hs', size %dx%d"),
					(const char *)fname, tilesize, tilesize);
				UpdateProgressDialog2(done*99/total, 0, msg);

				vtMiniDatabuf buf;
				buf.SetBounds(proj, tile_area);
				buf.alloc(tilesize+1, tilesize+1, 1, 1, bFloat ? 2 : 1);
				float *fdata = (float *) buf.data;
				short *sdata = (short *) buf.data;

				DPoint2 p;
				for (int y = base_tilesize; y >= 0; y -= (1<<lod))
				{
					p.y = area.bottom + (j*tile_dim.y) + ((double)y / base_tilesize * tile_dim.y);
					for (int x = 0; x <= base_tilesize; x += (1<<lod))
					{
						p.x = area.left + (i*tile_dim.x) + ((double)x / base_tilesize * tile_dim.x);

						if (bFloat)
						{
							*fdata = base_lod.GetFilteredValue(p);
							fdata++;
						}
						else
						{
							*sdata = (short) base_lod.GetFilteredValue(p);
							sdata++;
						}
					}
				}
				if (buf.savedata(fname) == 0)
				{
					// what should we do if writing a tile fails?
				}
			}
		}
	}
Beispiel #3
0
/**
 * Unarchives the indicated tarred, gzipped, or gzipped tar file.
 * Each directory and file in the archive is created.
 *
 * \param prepend_path A string to be prepended to all output filenames.
 *
 * \return -1 on error, otherwise the number of files the archive contained.
 */
int ExpandTGZ(const char *archive_fname, const char *prepend_path)
{
	gzFile	in;
	union	tar_buffer buffer;
	int		len;
	int		getheader = 1;
	int		remaining = 0;
	FILE	*outfile = NULL;
	char	fname[BLOCKSIZE];
	char	fullname[1024];
	time_t	tartime;
	int		files_encountered = 0;

	/*
	 *  Process the TGZ file
	 */
	in = gzopen(archive_fname, "rb");
	if (in == NULL)
	{
//		fprintf(stderr,"%s: Couldn't gzopen %s\n", prog, TGZfile);
		return -1;
	}

	while (1)
	{
		len = gzread(in, &buffer, BLOCKSIZE);
		if (len < 0)
		{
			// error (gzerror(in, &err));
			return -1;
		}
		/*
		* Always expect complete blocks to process
		* the tar information.
		*/
		if (len != BLOCKSIZE)
		{
			// error("gzread: incomplete block read");
			gzclose(in);
			return -1;
		}

		/*
		* If we have to get a tar header
		*/
		if (getheader == 1)
		{
			/*
			 * if we met the end of the tar
			 * or the end-of-tar block,
			 * we are done
			 */
			if ((len == 0) || (buffer.header.name[0]== 0)) break;

			tartime = (time_t)getoct(buffer.header.mtime, 12);
			strncpy(fname, buffer.header.name, BLOCKSIZE);

			strcpy(fullname, prepend_path);
			strcat(fullname, fname);

			switch (buffer.header.typeflag)
			{
			case DIRTYPE:
				vtCreateDir(fullname);
				break;
			case REGTYPE:
			case AREGTYPE:
				remaining = getoct(buffer.header.size, 12);
				if (remaining)
				{
					outfile = vtFileOpen(fullname,"wb");
					if (outfile == NULL)
					{
						/* try creating directory */
						char *p = strrchr(fullname, '/');
						if (p != NULL)
						{
							*p = '\0';
							vtCreateDir(fullname);
							*p = '/';
							outfile = vtFileOpen(fullname,"wb");
						}
					}
//					fprintf(stderr, "%s %s\n", (outfile) ? "Extracting" : "Couldn't create", fname);
					files_encountered++;
				}
				else
					outfile = NULL;
				/*
				 * could have no contents
				 */
				getheader = (remaining) ? 0 : 1;
				break;
			default:
				break;
			}
		}
		else
		{
			uint bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;

			if (outfile != NULL)
			{
				if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
				{
//					fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname);
					fclose(outfile);
					unlink(fname);
				}
			}
			remaining -= bytes;
			if (remaining == 0)
			{
				getheader = 1;
				if (outfile != NULL)
				{
#ifdef WIN32
					fclose(outfile);

					outfile = NULL;
#else
					struct utimbuf settime;

					settime.actime = settime.modtime = tartime;

					fclose(outfile);
					outfile = NULL;
					utime(fname,&settime);
#endif
				}
			}
		}
	}

	if (gzclose(in) != Z_OK)
	{
		// error("failed gzclose");
		return -1;
	}

	return files_encountered;
}