Advertisement
MakingGlitches

Copy gdal rloaded raster to png and save creating problems on msvc 2019

Apr 12th, 2021
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.95 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2.  
  3. #include <iostream>
  4. #include <iomanip>
  5. #include "gdal_priv.h"
  6. #include "cpl_conv.h"
  7. #include "proj.h"
  8. #include "ogr_core.h"
  9. #include "ogr_feature.h"
  10. #include "ogrsf_frmts.h"
  11. #include <windows.graphics.h>
  12. #include <math.h>
  13. #include "png.h"
  14.  
  15.  
  16.  
  17. void write_row_callback(png_structp png_ptr , png_uint_32 row,
  18.     int pass)
  19. {
  20.     /* put your code here */
  21. }
  22.  
  23. int main()
  24. {
  25.    
  26.     const char* filename = R"(C:\Users\John\Documents\CensusProject\CensusShapeFileData\TreeCanopy\nlcd_2016_treecanopy_2019_08_31\nlcd_2016_treecanopy_2019_08_31.img)";
  27.        
  28.     GDALDataset* poDataset;
  29.     GDALAllRegister();
  30.    
  31.     poDataset = (GDALDataset*)GDALOpen(filename, GA_ReadOnly);
  32.    
  33.     std::cout << "Raster Count: " << poDataset->GetRasterCount() << "\n";
  34.  
  35.     std::cout << "Projection Reference: " <<  poDataset->GetProjectionRef() << "\n";
  36.     std::cout << "Driver: " << poDataset->GetDriver()->GetDescription() << "\n";
  37.  
  38.     GDALDataset::Bands b =   poDataset->GetBands();
  39.    
  40.     std::cout << "Bands Size: " << b.size() << "\n";
  41.  
  42.     std::cout << poDataset->GetFileList() << "\n";
  43.  
  44.     std::cout << poDataset->GetGCPProjection() << "\n";
  45.  
  46.     std::cout << "Raster Count: " << poDataset->GetRasterCount() << "\n";
  47.  
  48.     GDALDataset::Features f = poDataset->GetFeatures();
  49.    
  50.  
  51.     for (auto&& flp  : poDataset->GetFeatures())
  52.     {
  53.         std::cout << "Feature of layer " <<
  54.           flp.layer->GetName()  << std::endl;  
  55.     }
  56.    
  57.     double coordbounds[6];
  58.  
  59.     std::cout << "Raster Size (X,Y): "<<  poDataset->GetRasterXSize() << ", " << poDataset->GetRasterYSize() << "\n";
  60.  
  61.     int rasterx = poDataset->GetRasterXSize();
  62.     int rastery = poDataset->GetRasterYSize();
  63.  
  64.  
  65.     if (poDataset->GetGeoTransform(coordbounds) == CE_None)
  66.     {
  67.         printf("Upper Left GeoX: %.5f\n", coordbounds[0]);
  68.         printf("Upper Left GeoY: %.5f\n", coordbounds[3]);
  69.         std::cout << "GeoX / Pixel:" << coordbounds[1] << std::endl;
  70.         std::cout << "GeoY / Pixel:" << coordbounds[5] << std::endl;
  71.      }
  72.  
  73.  
  74.     int blockx, blocky;
  75.    
  76.     GDALRasterBand* band = poDataset->GetRasterBand(1);
  77.  
  78.     band->GetBlockSize(&blockx, &blocky);
  79.  
  80.     std::cout << "This is probably all repeated. Actually sure it is. Remember blocky.\n"
  81.         << "Blocksize x: " << blockx
  82.         << "  Blocksize y: " << blocky << "\n";
  83.  
  84.    
  85.    
  86.     std::cout << "Raster Band Type: " << GDALGetDataTypeName(band->GetRasterDataType()) << std::endl;
  87.     std::cout << "Color Interpretation Name: " << GDALGetColorInterpretationName(band->GetColorInterpretation()) << std::endl;
  88.    
  89.     GDALColorTable* colors =   band->GetColorTable();
  90.        
  91.     GDALColorEntry* c = new GDALColorEntry();
  92.  
  93.     int ret = colors->GetColorEntryAsRGB(85, c);
  94.  
  95.  
  96.     void* buffer = new byte[512 * 512];
  97.  
  98.  
  99.     int x = 0;
  100.     int y = 0;
  101.  
  102.  
  103.     float tilesx = rasterx / 512.0;
  104.     float tilesy = rastery / 512.0;
  105.    
  106.     float excessx = rasterx - 512.0*trunc(tilesx);
  107.     float excessy = rastery - 512.0 * trunc(tilesy);
  108.  
  109.     int whol_tilesx = (int)ceilf(tilesx);
  110.     int whol_tilesy = (int)ceilf(tilesy);
  111.  
  112.  
  113.     std::cout << "Need to read: " << whol_tilesx << " x " << whol_tilesy << std::endl;
  114.     std::cout << "The last column will have: " << excessx << std::endl;
  115.     std::cout << "The last row will have: " << excessy << std::endl;
  116.  
  117.  
  118.     // retrieve a sample block of data from the raster.
  119.     CPLErr res = band->RasterIO(GF_Read, 0, 0, 512, 512, buffer, 512, 512, GDT_Byte, 1, 0, NULL);
  120.  
  121.     buffer = new byte[512 * 512];
  122.  
  123.     // populate the buffer object with a 512 block of data from the specific rasters UL corner
  124.     res = band->RasterIO(GF_Read, 161190-512, 104424-512,512,512,buffer, 512,512,GDT_Byte, 1, 0, NULL);
  125.  
  126.     // convenience typed pointer to buffer.
  127.     byte* bufbyte = (byte*)buffer;
  128.  
  129.  
  130.     // open a png file for writing.
  131.     FILE* pf =   fopen("test.png", "wb");
  132.  
  133.     // initialize the png write session.
  134.     png_structp png_ptr = png_create_write_struct
  135.     (PNG_LIBPNG_VER_STRING, NULL,
  136.         NULL,NULL);
  137.  
  138.     // error out if the pointer is null
  139.     if (!png_ptr)
  140.         return (ERROR);
  141.  
  142.     // create a png info pointer further configuring the code
  143.     png_infop info_ptr = png_create_info_struct(png_ptr);
  144.  
  145.     //again if the pointer is null error out
  146.     if (!info_ptr)
  147.     {
  148.         png_destroy_write_struct(&png_ptr,
  149.             (png_infopp)NULL);
  150.         return (ERROR);
  151.     }
  152.  
  153.     // i forget what this does :P
  154.     if (setjmp(png_jmpbuf(png_ptr)))
  155.     {
  156.         png_destroy_write_struct(&png_ptr, &info_ptr);
  157.         fclose(pf);
  158.         return (ERROR);
  159.     }
  160.  
  161.     // a bunch of png initialization routines, blah blah as per the manual section 5.3
  162.     png_init_io(png_ptr, pf);
  163.  
  164.     // this gets called i believe when a row is called to indicate status.
  165.     png_set_write_status_fn(png_ptr, write_row_callback);
  166.  
  167.     // in general this is a row by row comparison/ deduction operation meant to make the compression algorithm more efficient
  168.     // i left everything on, we'll see if that functions.
  169.     png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
  170.  
  171.     // choosing best compression, duh. trying to get that *****
  172.     // 20 GB file down considerably !
  173.     // each tile minus metadata is a 512^2 byte matrix of values relating to
  174.     // the palette. a downsize is i think png's compose a 4 byte per pixel or 32 bpp
  175.     // for full color, all i'll need is a 3 byte however or 24 bpp
  176.     // because the alpha channel is always 255.
  177.     png_set_compression_level(png_ptr, 9);
  178.        
  179.  
  180.     // https://www.euccas.me/zlib/#deflate_sliding_window
  181.     //https://refspecs.linuxbase.org/LSB_4.0.0/LSB-Desktop-generic/LSB-Desktop-generic/libpng-png-set-compression-window-bits-1.html
  182.     png_set_compression_window_bits(png_ptr, 10);
  183.  
  184.  
  185.     png_set_compression_method(png_ptr, 8);
  186.  
  187.     // in the zlib deflateinit2()  description it says to set this for filtered data.
  188.     png_set_compression_strategy(png_ptr, PNG_Z_DEFAULT_STRATEGY);
  189.  
  190.  
  191.     // ths is the input buffer size just tagged a meg more on top of it, this isnt a comp from the 1980s
  192.     // and only one of these processes will be running at a time.
  193.     png_set_compression_buffer_size(png_ptr, 1008192);
  194.  
  195.  
  196.     //section 4.3 of libpng-1.4.0 manual defines this pretty welll.
  197.     // we're stripping the alpha channel
  198.     // bit-depth signifies the individual color component possible values.
  199.     // which in this case seem to be limited 256x256x256 so, 8.
  200.     // the interlace value i'm kind of curious about
  201.     // as would this make zooming better or faster if i decide to display this data ?
  202.     // for now i'll set it to adam7
  203.     // documentation indicates to set the last two arguments to there defaults, makes me wonder why they are there at all.
  204.     png_set_IHDR(png_ptr, info_ptr, 512, 512, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  205.  
  206.     png_colorp pal = new png_color[256];
  207.  
  208.  
  209.     // copy the rasters pallette to the png pallete, this should allow values to be simply copied over.
  210.     for (int x = 0; x < 256; x++)
  211.     {
  212.         int ret = colors->GetColorEntryAsRGB(x, c);
  213.  
  214.         // simple conversion.
  215.         pal[x].red = (png_byte) c->c1;
  216.         pal[x].green = (png_byte) c->c2;
  217.         pal[x].blue = (png_byte) c->c3;
  218.     }
  219.    
  220.    
  221.     // set the png pallete
  222.     png_set_PLTE(png_ptr, info_ptr, pal, 256);
  223.  
  224.  
  225.     // set the comments section, for shits and giggles
  226.     png_textp comments = new png_text[3];
  227.     comments[0].compression = PNG_TEXT_COMPRESSION_NONE;
  228.     comments[0].text = (png_charp)"Treecanopy.img";
  229.     comments[0].text_length = 14; // strlen((char*)comments[1].text);
  230.     comments[0].key = (png_charp)"File";
  231.  
  232.  
  233.     comments[1].compression = PNG_TEXT_COMPRESSION_NONE;
  234.     comments[1].key = (png_charp) "Size";
  235.     comments[1].text = (png_charp)"512x512";
  236.     comments[1].text_length = 7; // strlen(comments[1].text);
  237.  
  238.     comments[2].compression = PNG_TEXT_COMPRESSION_NONE;
  239.     comments[2].key = (png_charp) "TilePos";
  240.     comments[2].text = (png_charp)"1x1";
  241.     comments[2].text_length = 3;// strlen(comments[2].text);
  242.  
  243.  
  244.     png_set_text(png_ptr, info_ptr, comments, 3);
  245.  
  246.     png_color_16*  backcol = new png_color_16();
  247.    
  248.     backcol->red = (png_uint_16)pal[0].red;
  249.     backcol->green = (png_uint_16)pal[0].green;
  250.     backcol->blue = (png_uint_16)pal[0].blue;
  251.  
  252.     png_set_bKGD(png_ptr, info_ptr, backcol);
  253.  
  254.     png_bytepp imgrows = new png_bytep[512];
  255.  
  256.     std::cout << "Copying sample tile to image rows:  ";
  257.  
  258.     for (int y = 0; y < 512; y++)
  259.     {
  260.         for (int x = 0; x < 512; x++)
  261.         {
  262.             imgrows[y] = new png_byte[512];
  263.             imgrows[y][x]=(png_byte)bufbyte[512 * y];
  264.         }
  265.     }
  266.  
  267.     std::cout << "done" << std::endl;
  268.      
  269.     png_set_rows(png_ptr, info_ptr,imgrows );
  270.  
  271.     png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
  272.  
  273.  
  274.     GDALClose((GDALDatasetH) poDataset);
  275.  
  276. }
  277.  
  278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement