HRESULT cDxCapture::WriteBitmapFromBuffer(const char* fileName, const BYTE *buffer, const long bufferSize)
{
	if (!m_mt.pbFormat)
		m_pGrabber->GetConnectedMediaType(&m_mt);

	VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)m_mt.pbFormat;
	HRESULT hr = WriteBitmap(fileName, &pVih->bmiHeader,
		m_mt.cbFormat - SIZE_PREHEADER, buffer, bufferSize);

	return hr;
}
Exemple #2
0
void framecapture_writebmpframes(int frames) {
    int frame;

    for (frame = 0; frames < frames; frames++) {
        printf("writebmp[%d]\n", frame);

        char fname[64];
        sprintf(fname, "%d.bmp", frame);

        WriteBitmap(fname,
                    (unsigned char *)(framesbuffer + (frame * FRAMESIZE)), 1280,
                    720, 4);
    }
}
Exemple #3
0
void StencilComp::Write (ostream& out) {
    GraphicComp::Write(out);
    UStencil* stencil = GetStencil();
    Bitmap* image, *mask;
    stencil->GetOriginal(image, mask);

    WriteBitmap(image, out);
    Mark(out);

    if (mask == nil) {
        out << no_mask;
    } else if (mask == image) {
        out << mask_equals_image;
    } else {
        out << valid_mask;
        WriteBitmap(mask, out);
    }

    WriteBgFilled(stencil->BgFilled(), out);
    WriteColor(stencil->GetFgColor(), out);
    WriteColor(stencil->GetBgColor(), out);
    WriteTransformer(stencil->GetTransformer(), out);
    WriteString(_filename, out);
}
int main(int argc, char* argv[])
{
   FILE  *fpout;
   
   BITMAP immagine;
   
   int n = atoi(argv[2]);
   int j,i;
  /* utilizzo:  copia_immagine file_originale.bmp file_copia.bmp */

  if (argc != 3 )
  {
     printf ("servono due argomenti!\n");
     exit (EXIT_FAILURE);
  }

  if ((fpout = fopen (argv[1], "wb")) == NULL)
  {
     printf ("errore di apertura del file copia\n");
     exit (EXIT_FAILURE);
  }
  

   immagine = CreateEmptyBitmap( n, n);

   for(i = 0; i < n; i++)
   {
      for(j = 0; j < n; j++)
      {
         if( (pow((n/2 - 10), 2) <= (pow(i-n/2,2)+pow(j-n/2, 2))) &&
               (pow(n/2, 2) >= (pow(i-n/2,2) + pow(j-n/2, 2))))
            PIXEL (immagine, i, j).red = 255;
         else
            PIXEL (immagine, i, j).blue = 255;
      }
   }
   
   WriteBitmap (immagine, fpout);

   ReleaseBitmapData (&immagine);

   return EXIT_SUCCESS;
}
int main (int argc, char *argv[])
{
   FILE *fpin, *fpout, *fptxt;
   BITMAP img;

   if (argc != 4)
   {                                                         
      printf ("ARGOMENTI: <file in> <file out> <textfile>\n");
      exit (EXIT_FAILURE);
   }

   if ((fpin = fopen (argv[1], "rb")) == NULL)
   {
      printf ("Error opening input file\n");
      exit (EXIT_FAILURE);
   }

   if ((fpout = fopen (argv[2], "wb")) == NULL)
   {
      printf ("Error opening output file\n");
      exit (EXIT_FAILURE);
   }

   if ((fptxt = fopen (argv[3], "r")) == NULL)
   {
      printf ("Error opening text file\n");
      exit (EXIT_FAILURE);
   }

   img = ReadBitmap (fpin);
   fclose (fpin);

   encode (img, fptxt);
   fclose (fptxt);

   WriteBitmap (img, fpout);
   fclose (fpout);

   ReleaseBitmapData (&img);

   return EXIT_SUCCESS;
}
Exemple #6
0
int _tmain(int argc, _TCHAR* argv[])
{
	if( argc < 2 )
	{
		_tprintf(_T("converts a picture to a tank skin\n"));
		_tprintf(_T("only 24-bit windows bitmaps supports\n"));
		_tprintf(_T("using: mkskin input_file.bmp [output_file.bmp]\n"));
		return 0;
	}

	_tprintf(_T("input file: \n  %s\n"), argv[1]);

	BITMAPFILEHEADER bmfh	= {0};
	BITMAPINFOHEADER bmih	= {0};

	RGBTRIPLE *pInputBits = NULL;
	if( !ReadBitmap(argv[1], &bmfh, &bmih, &pInputBits) )
		return -1;

	RGBTRIPLE *pOutputBits = new RGBTRIPLE[FRAME_WIDTH * FRAME_HEIGHT * FRAME_COUNT];
    MakeSkin(pOutputBits, pInputBits, &bmih);

	bmih.biSizeImage = FRAME_WIDTH * FRAME_HEIGHT * FRAME_COUNT * sizeof(RGBTRIPLE);
	bmfh.bfSize      = bmih.biSizeImage + bmfh.bfOffBits;
	bmih.biWidth     = FRAME_WIDTH * X_FRAMES;
	bmih.biHeight    = FRAME_HEIGHT * Y_FRAMES;

	_TCHAR outfn[MAX_PATH];
	if( argc > 2 ) _tcscpy(outfn, argv[2]);
	else _stprintf(outfn, _T("%s-skin.bmp"), argv[1]);

	_tprintf(_T("output file: \n  %s\n"), outfn);
	if( WriteBitmap(outfn, &bmfh, &bmih, pOutputBits) )
		_tprintf(_T("OK.\n"));
	else
		Sleep(1000);

	delete[] pOutputBits;
	delete[] pInputBits;
	return 0;
}
Exemple #7
0
int main()
{
#if defined(WRITE_BMP)
	BGR buf[OUTW*OUTH];
#else
	BGR buf[TILEW];
#endif

	memset(buf, 0, sizeof(buf));

	PixelWriter pix;
	pix.buffer = &buf[0];

#if defined(WRITE_BMP)
	Buffer<0,0,OUTW,OUTH,SceneTracer<TestScene,TestLights,OUTW,OUTH>::Tracer,
		TILEW,1>::Visit(pix);
	WriteBitmap("output.bmp", OUTW, OUTH, &buf[0]);
#else
	Tile<UX,UY,TILEW,1,SceneTracer<TestScene,TestLights,OUTW,OUTH>::Tracer>::Visit(pix);
	fwrite(&buf[0], 1, sizeof(buf), stdout);
#endif

	return 0;
}
Exemple #8
0
 void ImageWriter::WriteImage(Image* img, ProgressCallback* callback)
 {
     Managed<Bitmap> bmp = img->ToBitmap();
     WriteBitmap(bmp, callback);
 }
Exemple #9
0
/*
 * WriteBGFFile:  Write Bitmaps and Options structures out to given filename.
 *   Return FALSE on error.
 */
BOOL WriteBGFFile(Bitmaps *b, Options *opts, char *filename)
{
    int i, j, temp, max_indices, len;
    Group *g;
    file_node f;

    len = EstimateBGFFileSize(b);

    if (!MappedFileOpenWrite(filename, &f, len))
        return FALSE;

    // Write magic number
    for (i=0; i < 4; i++)
        if (MappedFileWrite(&f, &magic[i], 1) < 0) return FALSE;

    // Write version
    temp = VERSION;
    if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;

    // Write bitmap name
    if (MappedFileWrite(&f, &b->name, MAX_BITMAPNAME) < 0) return FALSE;

    // Write # of bitmaps
    if (MappedFileWrite(&f, &b->num_bitmaps, 4) < 0) return FALSE;

    // Write # of index groups
    if (MappedFileWrite(&f, &b->num_groups, 4) < 0) return FALSE;

    // Find most indices in a group
    max_indices = 0;
    for (i=0; i < b->num_groups; i++)
        if (b->groups[i].num_indices > max_indices)
            max_indices = b->groups[i].num_indices;
    if (MappedFileWrite(&f, &max_indices, 4) < 0) return FALSE;

    // Write shrink factor
    if (MappedFileWrite(&f, &opts->shrink, 4) < 0) return FALSE;

    // Write out bitmaps
    for (i=0; i < b->num_bitmaps; i++)
    {
        PDIB pdib = b->bitmaps[i];

        // Write out bitmap size (swap width and height if rotated)
        if (opts->rotate)
        {
            temp = DibHeight(pdib);
            if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;
            temp = DibWidth(pdib);
            if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;
        }
        else
        {
            temp = DibWidth(pdib);
            if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;
            temp = DibHeight(pdib);
            if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;
        }

        // Write out x and y offsets
        temp = b->offsets[i].x;
        if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;
        temp = b->offsets[i].y;
        if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE;

        // Write out hotspots
        if (MappedFileWrite(&f, &b->hotspots[i].num_hotspots, 1) < 0) return FALSE;
        for (j=0; j < b->hotspots[i].num_hotspots; j++)
        {
            if (MappedFileWrite(&f, &b->hotspots[i].numbers[j], 1) < 0) return FALSE;
            if (MappedFileWrite(&f, &b->hotspots[i].positions[j].x, 4) < 0) return FALSE;
            if (MappedFileWrite(&f, &b->hotspots[i].positions[j].y, 4) < 0) return FALSE;
        }

        // Write out the bytes of the bitmap
        if (!WriteBitmap(&f, pdib, opts)) return FALSE;
    }

    // Write out indices
    for (i=0; i < b->num_groups; i++)
    {
        g = &b->groups[i];
        if (MappedFileWrite(&f, &g->num_indices, 4) < 0) return FALSE;
        for (j=0; j < g->num_indices; j++)
            if (MappedFileWrite(&f, &g->indices[j], 4) < 0) return FALSE;
    }

    UnmapViewOfFile(f.mem);
    CloseHandle(f.mapfh);

    SetFilePointer(f.fh, (f.ptr - f.mem), NULL, FILE_BEGIN);
    SetEndOfFile(f.fh);

    CloseHandle(f.fh);
    return TRUE;
}
Exemple #10
0
int DetectFP(BYTE *ImgBuf,int Width,int Height, int HasFingerThreshold,int NoFingerThreshold,int Reverse,int DetectCount,int IsSingle)
{
	int v,avg_cur,avg_cur_div,avg_diff,m1,m2,size,pixel_diff,whiteSum=0,iTemp=0;
	int avgPixel=0;
/*	int ImgSize= Width*Height;

	BYTE *prev_fp = ImgBuf + (ImgSize),
		 *diff_fp = ImgBuf + (ImgSize) + DETECT_IMG_SIZE,
		 *cur_fp  = ImgBuf + (ImgSize) + (DETECT_IMG_SIZE <<1); */
//	printf(" ********** DetectFP ImgBuf=%p,prev_fp=%p,diff_fp=%p,cur_fp=%p \n",ImgBuf,prev_fp,diff_fp,cur_fp);
	static int LeaveFinger=0,
		   validCount=0,
		   pre_avg_cur_div=0;

	if(!CutDetectArea(ImgBuf,cur_fp,(Width>>1)-64 ,(Height>>1),Width,Height,DETECT_WIDTH,DETECT_HEIGHT))
	{
		return 0;
	}
	if(Reverse)
	{
		ReverseImage(cur_fp,DETECT_WIDTH,DETECT_HEIGHT);
	}
#ifdef DEBUGME
	WriteBitmap(cur_fp,DETECT_WIDTH,DETECT_HEIGHT,"fp_cut.bmp");
	WriteBitmap(ImgBuf,Width,Height,"fp_cut_src.bmp");
#endif
	CalcVar(cur_fp,DETECT_WIDTH,DETECT_HEIGHT,&avg_cur,&m1,&whiteSum,0);
	RegionDivideAdaptive((BYTE*)cur_fp,DETECT_WIDTH,DETECT_HEIGHT,-12,&avgPixel);
	size = DETECT_IMG_SIZE;
	for(v=0;v<size;v++)
	{
		if(cur_fp[v]==prev_fp[v])
			pixel_diff=255;
		else
			pixel_diff=0;
		diff_fp[v]=(BYTE)pixel_diff;
	}
	CalcVar(cur_fp,DETECT_WIDTH,DETECT_HEIGHT,&avg_cur_div,&m1,&iTemp,0);
	CalcVar(diff_fp,DETECT_WIDTH, DETECT_HEIGHT,&avg_diff,&m2,&iTemp,0);
	
#ifdef DEBUGME
	WriteBitmap(cur_fp, DETECT_WIDTH, DETECT_HEIGHT,"cur.bmp");
	WriteBitmap( prev_fp, DETECT_WIDTH, DETECT_HEIGHT,"prev.bmp");
	WriteBitmap( diff_fp,DETECT_WIDTH, DETECT_HEIGHT,"diff.bmp");
#endif
	if(!IsSingle && !LeaveFinger && (avg_cur_div<NoFingerThreshold || avg_diff>NoFingerThreshold))
	{
		LeaveFinger=TRUE;
		memcpy(prev_fp,cur_fp,DETECT_WIDTH*DETECT_HEIGHT);
		validCount=0; 
		pre_avg_cur_div=0;
	//	printf("No finger\n"); 
		return 0;
	}else if (IsSingle && ((avg_cur_div>HasFingerThreshold ) ||			//正常探测
			(avgPixel>180 && avg_cur_div>HasFingerThreshold-1200 ) || //适当考虑过湿指纹
			(avgPixel<80 &&  avg_cur_div>HasFingerThreshold+800 )))
	{
		return TRUE;
		
	}else if(LeaveFinger && ((avg_cur_div>HasFingerThreshold && avg_diff>NoFingerThreshold) ||			//正常探测
			(avgPixel>180 && avg_cur_div>HasFingerThreshold-1200 && avg_diff>NoFingerThreshold-1200) || //适当考虑过湿指纹
			(avgPixel<80 &&  avg_cur_div>HasFingerThreshold+800 && avg_diff>NoFingerThreshold+800)))	//适当过滤残留指纹
	{
	//	printf("debug me avg_cur_div=%d,count=%d,avgPixel=%d\n",avg_cur_div,validCount,avgPixel);
		validCount++;
		if(validCount==DetectCount)
		{
			//filter black background
			if(avgPixel>216 || (avg_cur<696 && avgPixel>136 && whiteSum<104) || (avg_cur<480 && avgPixel>120))
			{
				validCount=0;
				DBPRINTF("a fake finger\n");
				//write_bitmap("/mnt/ramdisk/finger_fake.bmp",ImgBuf,Width,Height);
				return FALSE;
			}
			//write_bitmap("/mnt/ramdisk/finger.bmp",ImgBuf,Width,Height);
					
			LeaveFinger=FALSE;
			memcpy(prev_fp,cur_fp,DETECT_IMG_SIZE);
#ifdef DEBUGME 	//get a best finger image
			if(validCount>1 && pre_avg_cur_div> avg_cur_div)
				memcpy(ImgBuf,ImgBuf+ImgSize,ImgSize);
#endif
			pre_avg_cur_div = 0;
			validCount=0;

			return TRUE;
		}else
		{
			pre_avg_cur_div = avg_cur_div;
#ifdef DEBUGME
			memcpy(ImgBuf+ImgSize,ImgBuf,ImgSize);
#endif
			return 0;
		}
	}else
	{
		//_RPT3(0,"else debug me avg_cur_div=%d,avg_diff=%d,avgPixel=%d\n",avg_cur_div,avg_diff,avgPixel);
	//	printf("else debug me avg_cur_div=%d,avg_diff=%d,avgPixel=%d\n",avg_cur_div,avg_diff,avgPixel);
		validCount=0;
		pre_avg_cur_div=0;
		if(LeaveFinger && avgPixel>180)
			return FALSE;// -1;
		else
			return FALSE;
	}
}
Exemple #11
0
NS_IMETHODIMP
nsWindowsHooks::SetImageAsWallpaper(nsIDOMElement* aElement, PRBool aUseBackground)
{
  nsresult rv;
  
  nsCOMPtr<gfxIImageFrame> gfxFrame;
  if (aUseBackground) {
    // XXX write background loading stuff!
  } else {
    nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
    if (!imageContent) return rv;
    
    // get the image container
    nsCOMPtr<imgIRequest> request;
    rv = imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                                  getter_AddRefs(request));
    if (!request) return rv;
    nsCOMPtr<imgIContainer> container;
    rv = request->GetImage(getter_AddRefs(container));
    if (!container)
      return NS_ERROR_FAILURE;
    
    // get the current frame, which holds the image data
    container->GetCurrentFrame(getter_AddRefs(gfxFrame));
  }  
  
  if (!gfxFrame)
    return NS_ERROR_FAILURE;

  // get the profile root directory
  nsCOMPtr<nsIFile> file;
  rv = NS_GetSpecialDirectory(NS_APP_APPLICATION_REGISTRY_DIR,
                              getter_AddRefs(file));
  NS_ENSURE_SUCCESS(rv, rv);
  
  // get the product brand name from localized strings
  nsXPIDLString brandName, fileLeafName;
  nsCOMPtr<nsIStringBundleService> bundleService =
           do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
  NS_ENSURE_TRUE(bundleService, rv);

  // get the product brand name from localized strings
  nsCOMPtr<nsIStringBundle> bundle;
  rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties",
                                   getter_AddRefs(bundle));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
                                 getter_Copies(brandName));
  NS_ENSURE_SUCCESS(rv, rv);

  // get the file leaf name from localized strings (e.g. "%S Wallpaper.bmp")
  rv = bundleService->CreateBundle("chrome://global-platform/locale/nsWindowsHooks.properties",
                                   getter_AddRefs(bundle));
  NS_ENSURE_SUCCESS(rv, rv);

  const PRUnichar* stringArray[] = { brandName.get() };

  rv = bundle->FormatStringFromName(NS_LITERAL_STRING("wallpaperFile").get(),
                                    stringArray, NS_ARRAY_LENGTH(stringArray),
                                    getter_Copies(fileLeafName));
  NS_ENSURE_SUCCESS(rv, rv);
  
  // eventually, the path is %APPDATA%\Mozilla\Mozilla Wallpaper.bmp
  fileLeafName.AppendLiteral(".bmp");
  rv = file->Append(fileLeafName);
  NS_ENSURE_SUCCESS(rv, rv);

  // write the bitmap to the target file
  rv = WriteBitmap(file, gfxFrame);
  NS_ENSURE_SUCCESS(rv, rv);

  // set it as the system wallpaper
  nsCAutoString nativePath;
  rv = file->GetNativePath(nativePath);
  NS_ENSURE_SUCCESS(rv, rv);
  
  ::SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID) nativePath.get(),
                         SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

  return rv;
}
Exemple #12
0
  bool AreaWayIndexGenerator::Import(const ImportParameter& parameter,
                                     Progress& progress,
                                     const TypeConfig& typeConfig)
  {
    FileScanner           wayScanner;
    FileWriter            writer;
    std::set<TypeId>      remainingWayTypes;
    std::vector<TypeData> wayTypeData;
    size_t                level;
    size_t                maxLevel=0;

    wayTypeData.resize(typeConfig.GetTypes().size());

    if (!wayScanner.Open(AppendFileToDir(parameter.GetDestinationDirectory(),
                                         "ways.dat"),
                         FileScanner::Sequential,
                         parameter.GetWayDataMemoryMaped())) {
      progress.Error("Cannot open 'ways.dat'");
      return false;
    }

    //
    // Scanning distribution
    //

    progress.SetAction("Scanning level distribution of way types");

    for (size_t i=0; i<typeConfig.GetTypes().size(); i++) {
      if (typeConfig.GetTypeInfo(i).CanBeWay() &&
          !typeConfig.GetTypeInfo(i).GetIgnore()) {
        remainingWayTypes.insert(i);
      }
    }

    level=parameter.GetAreaWayMinMag();
    while (!remainingWayTypes.empty()) {
      uint32_t                   wayCount=0;
      std::set<TypeId>           currentWayTypes(remainingWayTypes);
      double                     cellWidth=360.0/pow(2.0,(int)level);
      double                     cellHeight=180.0/pow(2.0,(int)level);
      std::vector<CoordCountMap> cellFillCount(typeConfig.GetTypes().size());

      progress.Info("Scanning Level "+NumberToString(level)+" ("+NumberToString(remainingWayTypes.size())+" types remaining)");

      wayScanner.GotoBegin();

      if (!wayScanner.Read(wayCount)) {
        progress.Error("Error while reading number of data entries in file");
        return false;
      }

      Way way;

      for (uint32_t w=1; w<=wayCount; w++) {
        progress.SetProgress(w,wayCount);

        if (!way.Read(wayScanner)) {
          progress.Error(std::string("Error while reading data entry ")+
                         NumberToString(w)+" of "+
                         NumberToString(wayCount)+
                         " in file '"+
                         wayScanner.GetFilename()+"'");
          return false;
        }

        // Count number of entries per current type and coordinate
        if (currentWayTypes.find(way.GetType())==currentWayTypes.end()) {
          continue;
        }

        double minLon;
        double maxLon;
        double minLat;
        double maxLat;

        way.GetBoundingBox(minLon,maxLon,minLat,maxLat);

        //
        // Calculate minimum and maximum tile ids that are covered
        // by the way
        // Renormated coordinate space (everything is >=0)
        //
        uint32_t minxc=(uint32_t)floor((minLon+180.0)/cellWidth);
        uint32_t maxxc=(uint32_t)floor((maxLon+180.0)/cellWidth);
        uint32_t minyc=(uint32_t)floor((minLat+90.0)/cellHeight);
        uint32_t maxyc=(uint32_t)floor((maxLat+90.0)/cellHeight);

        for (uint32_t y=minyc; y<=maxyc; y++) {
          for (uint32_t x=minxc; x<=maxxc; x++) {
            cellFillCount[way.GetType()][Pixel(x,y)]++;
          }
        }
      }

      // Check if cell fill for current type is in defined limits
      for (size_t i=0; i<typeConfig.GetTypes().size(); i++) {
        if (currentWayTypes.find(i)!=currentWayTypes.end()) {
          CalculateStatistics(level,wayTypeData[i],cellFillCount[i]);

          if (!FitsIndexCriteria(parameter,
                                 progress,
                                 typeConfig.GetTypeInfo(i),
                                 wayTypeData[i],
                                 cellFillCount[i])) {
            currentWayTypes.erase(i);
          }
        }
      }

      for (std::set<TypeId>::const_iterator cwt=currentWayTypes.begin();
           cwt!=currentWayTypes.end();
           cwt++) {
        maxLevel=std::max(maxLevel,level);

        progress.Info("Type "+typeConfig.GetTypeInfo(*cwt).GetName()+"(" + NumberToString(*cwt)+"), "+NumberToString(wayTypeData[*cwt].indexCells)+" cells, "+NumberToString(wayTypeData[*cwt].indexEntries)+" objects");

        remainingWayTypes.erase(*cwt);
      }

      level++;
    }

    //
    // Writing index file
    //

    progress.SetAction("Generating 'areaway.idx'");

    if (!writer.Open(AppendFileToDir(parameter.GetDestinationDirectory(),
                                     "areaway.idx"))) {
      progress.Error("Cannot create 'areaway.idx'");
      return false;
    }

    uint32_t indexEntries=0;

    for (size_t i=0; i<typeConfig.GetTypes().size(); i++)
    {
      if (typeConfig.GetTypeInfo(i).CanBeWay() &&
          wayTypeData[i].HasEntries()) {
        indexEntries++;
      }
    }

    writer.Write(indexEntries);

    for (size_t i=0; i<typeConfig.GetTypes().size(); i++)
    {
      if (typeConfig.GetTypeInfo(i).CanBeWay() &&
          wayTypeData[i].HasEntries()) {
        uint8_t    dataOffsetBytes=0;
        FileOffset bitmapOffset=0;

        writer.WriteNumber(typeConfig.GetTypeInfo(i).GetId());

        writer.GetPos(wayTypeData[i].indexOffset);

        writer.WriteFileOffset(bitmapOffset);

        if (wayTypeData[i].HasEntries()) {
          writer.Write(dataOffsetBytes);
          writer.WriteNumber(wayTypeData[i].indexLevel);
          writer.WriteNumber(wayTypeData[i].cellXStart);
          writer.WriteNumber(wayTypeData[i].cellXEnd);
          writer.WriteNumber(wayTypeData[i].cellYStart);
          writer.WriteNumber(wayTypeData[i].cellYEnd);
        }
      }
    }

    for (size_t l=parameter.GetAreaWayMinMag(); l<=maxLevel; l++) {
      std::set<TypeId> indexTypes;
      uint32_t         wayCount;
      double           cellWidth=360.0/pow(2.0,(int)l);
      double           cellHeight=180.0/pow(2.0,(int)l);

      for (size_t i=0; i<typeConfig.GetTypes().size(); i++) {
        if (typeConfig.GetTypeInfo(i).CanBeWay() &&
            wayTypeData[i].HasEntries() &&
            wayTypeData[i].indexLevel==l) {
          indexTypes.insert(i);
        }
      }

      if (indexTypes.empty()) {
        continue;
      }

      progress.Info("Scanning ways for index level "+NumberToString(l));

      std::vector<CoordOffsetsMap> typeCellOffsets(typeConfig.GetTypes().size());

      wayScanner.GotoBegin();

      if (!wayScanner.Read(wayCount)) {
        progress.Error("Error while reading number of data entries in file");
        return false;
      }

      Way way;

      for (uint32_t w=1; w<=wayCount; w++) {
        progress.SetProgress(w,wayCount);

        FileOffset offset;

        wayScanner.GetPos(offset);

        if (!way.Read(wayScanner)) {
          progress.Error(std::string("Error while reading data entry ")+
                         NumberToString(w)+" of "+
                         NumberToString(wayCount)+
                         " in file '"+
                         wayScanner.GetFilename()+"'");
          return false;
        }

        if (indexTypes.find(way.GetType())==indexTypes.end()) {
          continue;
        }

        double minLon;
        double maxLon;
        double minLat;
        double maxLat;

        way.GetBoundingBox(minLon,maxLon,minLat,maxLat);

        //
        // Calculate minimum and maximum tile ids that are covered
        // by the way
        // Renormated coordinate space (everything is >=0)
        //
        uint32_t minxc=(uint32_t)floor((minLon+180.0)/cellWidth);
        uint32_t maxxc=(uint32_t)floor((maxLon+180.0)/cellWidth);
        uint32_t minyc=(uint32_t)floor((minLat+90.0)/cellHeight);
        uint32_t maxyc=(uint32_t)floor((maxLat+90.0)/cellHeight);

        for (uint32_t y=minyc; y<=maxyc; y++) {
          for (uint32_t x=minxc; x<=maxxc; x++) {
            typeCellOffsets[way.GetType()][Pixel(x,y)].push_back(offset);
          }
        }
      }

      for (std::set<TypeId>::const_iterator type=indexTypes.begin();
           type!=indexTypes.end();
           ++type) {
        if (!WriteBitmap(progress,
                         writer,
                         typeConfig.GetTypeInfo(*type),
                         wayTypeData[*type],
                         typeCellOffsets[*type])) {
          return false;
        }
      }
    }

    return !writer.HasError() && writer.Close();
  }
  bool AreaWayIndexGenerator::Import(const TypeConfigRef& typeConfig,
                                     const ImportParameter& parameter,
                                     Progress& progress)
  {
    FileScanner           wayScanner;
    FileWriter            writer;
    std::vector<TypeData> wayTypeData;
    size_t                maxLevel;

    progress.Info("Minimum magnification: "+NumberToString(parameter.GetAreaWayMinMag()));

    //
    // Scanning distribution
    //

    progress.SetAction("Scanning level distribution of way types");

    if (!CalculateDistribution(typeConfig,
                               parameter,
                               progress,
                               wayTypeData,
                               maxLevel)) {
      return false;
    }

    // Calculate number of types which have data

    uint32_t indexEntries=0;

    for (const auto& type : typeConfig->GetWayTypes())
    {
      if (wayTypeData[type->GetIndex()].HasEntries()) {
        indexEntries++;
      }
    }

    //
    // Writing index file
    //

    progress.SetAction("Generating 'areaway.idx'");

    if (!writer.Open(AppendFileToDir(parameter.GetDestinationDirectory(),
                                     "areaway.idx"))) {
      progress.Error("Cannot create 'areaway.idx'");
      return false;
    }

    writer.Write(indexEntries);

    for (const auto &type : typeConfig->GetWayTypes()) {
      size_t i=type->GetIndex();

      if (wayTypeData[i].HasEntries()) {
        uint8_t    dataOffsetBytes=0;
        FileOffset bitmapOffset=0;

        writer.WriteTypeId(type->GetWayId(),
                           typeConfig->GetWayTypeIdBytes());

        writer.GetPos(wayTypeData[i].indexOffset);

        writer.WriteFileOffset(bitmapOffset);
        writer.Write(dataOffsetBytes);
        writer.WriteNumber(wayTypeData[i].indexLevel);
        writer.WriteNumber(wayTypeData[i].cellXStart);
        writer.WriteNumber(wayTypeData[i].cellXEnd);
        writer.WriteNumber(wayTypeData[i].cellYStart);
        writer.WriteNumber(wayTypeData[i].cellYEnd);
      }
    }

    if (!wayScanner.Open(AppendFileToDir(parameter.GetDestinationDirectory(),
                                         "ways.dat"),
                         FileScanner::Sequential,
                         parameter.GetWayDataMemoryMaped())) {
      progress.Error("Cannot open 'ways.dat'");
      return false;
    }

    for (size_t l=parameter.GetAreaWayMinMag(); l<=maxLevel; l++) {
      TypeInfoSet indexTypes(*typeConfig);
      uint32_t    wayCount;
      double      cellWidth=360.0/pow(2.0,(int)l);
      double      cellHeight=180.0/pow(2.0,(int)l);

      wayScanner.GotoBegin();

      for (const auto &type : typeConfig->GetWayTypes()) {
        if (wayTypeData[type->GetIndex()].HasEntries() &&
            wayTypeData[type->GetIndex()].indexLevel==l) {
          indexTypes.Set(type);
        }
      }

      if (indexTypes.Empty()) {
        continue;
      }

      progress.Info("Scanning ways for index level "+NumberToString(l));

      std::vector<CoordOffsetsMap> typeCellOffsets(typeConfig->GetTypeCount());

      if (!wayScanner.Read(wayCount)) {
        progress.Error("Error while reading number of data entries in file");
        return false;
      }

      Way way;

      for (uint32_t w=1; w<=wayCount; w++) {
        progress.SetProgress(w,wayCount);

        FileOffset offset;

        wayScanner.GetPos(offset);

        if (!way.Read(*typeConfig,
                      wayScanner)) {
          progress.Error(std::string("Error while reading data entry ")+
                         NumberToString(w)+" of "+
                         NumberToString(wayCount)+
                         " in file '"+
                         wayScanner.GetFilename()+"'");
          return false;
        }

        if (!indexTypes.IsSet(way.GetType())) {
          continue;
        }

        GeoBox boundingBox;

        way.GetBoundingBox(boundingBox);

        //
        // Calculate minimum and maximum tile ids that are covered
        // by the way
        // Renormalized coordinate space (everything is >=0)
        //
        uint32_t minxc=(uint32_t)floor((boundingBox.GetMinLon()+180.0)/cellWidth);
        uint32_t maxxc=(uint32_t)floor((boundingBox.GetMaxLon()+180.0)/cellWidth);
        uint32_t minyc=(uint32_t)floor((boundingBox.GetMinLat()+90.0)/cellHeight);
        uint32_t maxyc=(uint32_t)floor((boundingBox.GetMaxLat()+90.0)/cellHeight);

        for (uint32_t y=minyc; y<=maxyc; y++) {
          for (uint32_t x=minxc; x<=maxxc; x++) {
            typeCellOffsets[way.GetType()->GetIndex()][Pixel(x,y)].push_back(offset);
          }
        }
      }

      for (const auto &type : indexTypes) {
        size_t index=type->GetIndex();

        if (!WriteBitmap(progress,
                         writer,
                         *typeConfig->GetTypeInfo(index),
                         wayTypeData[index],
                         typeCellOffsets[index])) {
          return false;
        }
      }
    }

    return !writer.HasError() && writer.Close();
  }