Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first working iip + openslide build

  • Loading branch information...
commit eca4004303f847c09cff5dc055b46c75695b0886 1 parent 8613d63
@richstoner authored
View
25 src/CVT.cc
@@ -178,6 +178,10 @@ void CVT::run( Session* session, const std::string& a ){
session->view->getLayers(),
view_left, view_top, view_width, view_height );
+ *(session->logfile) << "Openslide test :: getting here" << endl;
+
+
+
if( session->loglevel >= 4 ){
if( session->view->getContrast() != 1.0 ){
*(session->logfile) << "CVT :: Applying contrast of: " << session->view->getContrast() << endl;
@@ -186,6 +190,8 @@ void CVT::run( Session* session, const std::string& a ){
<< " bit data to 8" << endl;
}
+ *(session->logfile) << "Openslide test :: getting here 1" << endl;
+
// Convert CIELAB to sRGB
if( (*session->image)->getColourSpace() == CIELAB ){
@@ -201,6 +207,8 @@ void CVT::run( Session* session, const std::string& a ){
}
}
+ *(session->logfile) << "Openslide test :: getting here 2" << endl;
+
// Apply color mapping if requested
if( session->view->cmapped ){
@@ -212,6 +220,8 @@ void CVT::run( Session* session, const std::string& a ){
channels = 3;
}
+ *(session->logfile) << "Openslide test :: getting here 3" << endl;
+
// Apply hill shading if requested
if( session->view->shaded ){
@@ -223,6 +233,8 @@ void CVT::run( Session* session, const std::string& a ){
channels = 1;
}
+ *(session->logfile) << "Openslide test :: getting here 4" << endl;
+
// Resize our image as requested. Use the interpolation method requested in the server configuration.
// - Use bilinear interpolation by default
@@ -249,6 +261,9 @@ void CVT::run( Session* session, const std::string& a ){
}
}
+ *(session->logfile) << "Openslide test :: getting here 5" << endl;
+
+
// Apply any gamma correction
if( session->view->getGamma() != 1.0 ){
@@ -260,10 +275,17 @@ void CVT::run( Session* session, const std::string& a ){
}
+ *(session->logfile) << "Openslide test :: getting here 6" << endl;
+
+
// Apply any contrast adjustments and/or clipping to 8bit from 16bit or 32bit
filter_contrast( complete_image, session->view->getContrast(), (*session->image)->max, (*session->image)->min );
+ *(session->logfile) << "Openslide test :: getting here 7" << endl;
+
+
+
// Convert to greyscale if requested
if( (*session->image)->getColourSpace() == sRGB && session->view->colourspace == GREYSCALE ){
@@ -281,6 +303,9 @@ void CVT::run( Session* session, const std::string& a ){
}
}
+ *(session->logfile) << "Openslide test :: getting here 8" << endl;
+
+
// Apply rotation - can apply this safely after gamma and contrast adjustment
if( session->view->getRotation() != 0.0 ){
View
2  src/Environment.h
@@ -26,7 +26,7 @@
*/
#define VERBOSITY 1
#define LOGFILE "/tmp/iipsrv.log"
-#define MAX_IMAGE_CACHE_SIZE 10.0
+#define MAX_IMAGE_CACHE_SIZE 0.0
#define FILENAME_PATTERN "_pyr_"
#define JPEG_QUALITY 75
#define MAX_CVT 5000
View
12 src/FIF.cc
@@ -31,6 +31,8 @@
#define MAXIMAGECACHE 500 // Max number of items in image cache
+#include "OpenSlideImage.h"
+
using namespace std;
@@ -122,6 +124,7 @@ void FIF::run( Session* session, const string& src ){
// Check whether cache is empty
if( session->imageCache->empty() ){
+ // if( true ){
if( session->loglevel >= 1 ) *(session->logfile) << "FIF :: Image cache initialisation" << endl;
test = IIPImage( argument );
test.setFileNamePattern( filename_pattern );
@@ -164,6 +167,15 @@ void FIF::run( Session* session, const string& src ){
if( session->loglevel >= 2 ) *(session->logfile) << "FIF :: TIFF image requested" << endl;
*session->image = new TPTImage( test );
}
+#pragma mark Adding in basic openslide functionality
+ else if (imtype=="svs") {
+
+ if( session->loglevel >= 2 ) *(session->logfile) << "FIF :: OpenSlide image requested" << endl;
+
+ *session->image = new OpenSlideImage( test );
+
+ }
+
#ifdef HAVE_KAKADU
else if( imtype=="jpx" || imtype=="jp2" || imtype=="j2k" ){
if( session->loglevel >= 2 ) *(session->logfile) << "FIF :: JPEG2000 image requested" << endl;
View
2  src/Main.cc
@@ -75,7 +75,7 @@ static void unsetenv(char *env_name) {
#endif
-//#define DEBUG 1
+// #define DEBUG 1
using namespace std;
View
7 src/Makefile.am
@@ -4,8 +4,9 @@ noinst_PROGRAMS = iipsrv.fcgi
INCLUDES = @INCLUDES@ @LIBFCGI_INCLUDES@ @JPEG_INCLUDES@ @TIFF_INCLUDES@
-LIBS = @LIBS@ @LIBFCGI_LIBS@ @DL_LIBS@ @JPEG_LIBS@ @TIFF_LIBS@ -lm
-AM_LDFLAGS = @LIBFCGI_LDFLAGS@
+LIBS = @LIBS@ @LIBFCGI_LIBS@ @DL_LIBS@ @JPEG_LIBS@ @TIFF_LIBS@ -lm -lopenslide
+AM_LDFLAGS = @LIBFCGI_LDFLAGS@ -L/usr/local/lib/openslide
+AM_CPPFLAGS = -I/usr/local/include/openslide
iipsrv_fcgi_LDADD = Main.o
@@ -28,6 +29,8 @@ iipsrv_fcgi_SOURCES = \
IIPImage.cc \
TPTImage.h \
TPTImage.cc \
+ OpenSlideImage.h \
+ OpenSlideImage.cc \
JPEGCompressor.h \
JPEGCompressor.cc \
RawTile.h \
View
638 src/OpenSlideImage.cc
@@ -0,0 +1,638 @@
+// Member functions for TPTImage.h
+
+/* IIP Server: Tiled Pyramidal TIFF handler
+
+ Copyright (C) 2000-2013 Ruven Pillay.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+
+#include "OpenSlideImage.h"
+#include <sstream>
+
+#include <stdio.h>
+#include <openslide.h>
+//#include <cstdio>
+//#include <iostream>
+
+using namespace std;
+extern std::ofstream logfile;
+
+void OpenSlideImage::openImage() throw (string)
+{
+
+ FILE *fp;
+ fp = fopen("/vagrant/openImage.log", "w");
+
+ if( osr || osr_buf ){
+
+ fprintf(fp, "osr or osr_buf is not null\n");
+ fclose(fp);
+
+ throw string( "OpenSlideImage::openImage: osr or osr_buf is not NULL" );
+ }
+ else{
+ fprintf(fp, "osr & osb_buf are NULL\n");
+
+ }
+
+ string filename = getFileName( currentX, currentY );
+
+ fprintf(fp, "opening %s", filename.c_str());
+
+ // Update our timestamp
+ updateTimestamp( filename );
+
+ osr = openslide_open( filename.c_str());
+
+ if(osr == NULL){
+
+ fprintf(fp, "openslide failed to open for %s\n",filename.c_str());
+
+ fclose(fp);
+
+ throw string("openslide open failed for: " + filename);
+
+ }
+ else{
+
+ fprintf(fp, "openslide successfully opened %s\n", filename.c_str());
+
+ }
+
+
+ // Load our metadata if not already loaded
+ if( bpp == 0 ){
+ loadImageInfo( currentX, currentY );
+ }
+
+ fprintf(fp, "bpp for this image is %d\n", bpp);
+
+ // Insist on a tiled image
+ if( (tile_width == 0) && (tile_height == 0) ){
+ fclose(fp);
+ throw string( "OpenSlide image is not tiled" );
+ }
+
+ isSet = true;
+
+ fclose(fp);
+
+
+}
+
+
+
+
+void OpenSlideImage::loadImageInfo( int seq, int ang ) throw(string)
+{
+
+ logfile << "OpenSlideImage :: loadImageInfo()" << endl;
+
+ int count;
+ // uint16 colour, samplesperpixel, bitspersample, sampleformat;
+ double sminvalue[4], smaxvalue[4];
+ unsigned int w, h;
+ int64_t big_w,big_h;
+
+ currentX = seq;
+ currentY = ang;
+
+ tile_width = 256;
+ tile_height = 256;
+ ;
+
+ int level_count = openslide_get_level_count(osr);
+
+ logfile << "OpenSlideImage :: image levels " << level_count << endl;
+
+ for(count = 0; count < level_count; count++)
+ {
+ openslide_get_level_dimensions(osr, level_count - count - 1, &big_w, &big_h);
+
+ w = (unsigned int)big_w;
+ h = (unsigned int)big_h;
+
+ image_widths.push_back(w);
+ image_heights.push_back(h);
+
+ logfile << "OpenSlideImage :: resolution for level " << count << " " << w << " x " << h << endl;
+ }
+
+ sampleType = FIXEDPOINT;
+ numResolutions = count + 1;
+ channels = 3;
+ colourspace = sRGB;
+ bpp = 8;
+
+ min.clear();
+ max.clear();
+ for( int i=0; i<channels; i++ ){
+ if( (float)smaxvalue[i] == 0.0 ){
+ sminvalue[i] = 0.0;
+ // Set default values if values not included in header
+ if( bpp == 8 ) smaxvalue[i] = 255.0;
+ else if( bpp == 16 ) smaxvalue[i] = 65535.0;
+ else if( bpp == 32 && sampleType == FIXEDPOINT ) smaxvalue[i] = 4294967295.0;
+ }
+ min.push_back( (float)sminvalue[i] );
+ max.push_back( (float)smaxvalue[i] );
+ }
+
+ // // Handle various colour spaces
+ // if( colour == PHOTOMETRIC_CIELAB ) colourspace = CIELAB;
+ // else if( colour == PHOTOMETRIC_MINISBLACK ) colourspace = GREYSCALE;
+ // else if( colour == PHOTOMETRIC_PALETTE ){
+ // // Watch out for colourmapped images. These are stored as 1 sample per pixel,
+ // // but are decoded to 3 channels by libtiff, so declare them as sRGB
+ // colourspace = sRGB;
+ // channels = 3;
+ // }
+ // else if( colour == PHOTOMETRIC_YCBCR ){
+ // // JPEG encoded tiles can be subsampled YCbCr encoded. Ask to decode these to RGB
+ // TIFFSetField( tiff, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
+ // colourspace = sRGB;
+ // }
+ // else colourspace = sRGB;
+
+ // // Get the max and min values for our data type - required for floats
+ // TIFFGetFieldDefaulted( tiff, TIFFTAG_SMINSAMPLEVALUE, sminvalue );
+ // TIFFGetFieldDefaulted( tiff, TIFFTAG_SMAXSAMPLEVALUE, smaxvalue )
+
+ // // Also get some basic metadata
+ // if( TIFFGetField( tiff, TIFFTAG_ARTIST, &tmp ) ) metadata["author"] = tmp;
+ // if( TIFFGetField( tiff, TIFFTAG_COPYRIGHT, &tmp ) ) metadata["copyright"] = tmp;
+ // if( TIFFGetField( tiff, TIFFTAG_DATETIME, &tmp ) ) metadata["create-dtm"] = tmp;
+ // if( TIFFGetField( tiff, TIFFTAG_IMAGEDESCRIPTION, &tmp ) ) metadata["subject"] = tmp;
+ // if( TIFFGetField( tiff, TIFFTAG_SOFTWARE, &tmp ) ) metadata["app-name"] = tmp;
+ // if( TIFFGetField( tiff, TIFFTAG_XMLPACKET, &count, &tmp ) ) metadata["xmp"] = string(tmp,count);
+
+}
+
+
+void OpenSlideImage::closeImage()
+{
+ FILE *fp;
+ fp = fopen("/vagrant/closeImage.log", "a");
+ fprintf(fp, "close Image\n");
+ fclose(fp);
+
+ if (osr != NULL)
+ {
+ openslide_close(osr);
+ osr = NULL;
+ }
+
+ if (osr_buf != NULL)
+ {
+ free(osr_buf);
+ osr_buf = NULL;
+ }
+
+
+ fp = fopen("/vagrant/closeImage.log", "a");
+ fprintf(fp, "image close successful\n");
+ fclose(fp);
+
+
+
+ // if( tiff != NULL ){
+ // TIFFClose( tiff );
+ // tiff = NULL;
+ // }
+ // if( tile_buf != NULL ){
+ // _TIFFfree( tile_buf );
+ // tile_buf = NULL;
+ // }
+}
+
+
+RawTile OpenSlideImage::getTile( int seq, int ang, unsigned int res, int layers, unsigned int tile ) throw (string)
+{
+ unsigned int im_width, im_height, tw, th, ntlx, ntly;
+ unsigned int rem_x, rem_y;
+ unsigned short colour;
+
+ string filename;
+
+
+ FILE *fp;
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "getTile\n");
+
+
+ fprintf(fp, "seq: %d\n", seq);
+ fprintf(fp, "ang: %d\n", ang);
+ fprintf(fp, "res: %d\n", res);
+ fprintf(fp, "layers: %d\n", layers);
+ fprintf(fp, "tile: %d\n", tile);
+
+ fprintf(fp, "curX: %d\n", currentX);
+ fprintf(fp, "curY: %d\n", currentY);
+
+
+
+ fclose(fp);
+
+
+
+ // // Check the resolution exists
+// if( res > numResolutions ){
+// ostringstream error;
+// error << "TPTImage :: Asked for non-existant resolution: " << res;
+// throw error.str();
+// }
+
+
+ // If we are currently working on a different sequence number, then
+ // close and reload the image.
+ if( (currentX != seq) || (currentY != ang) ){
+ closeImage();
+ }
+
+
+ // // Open the TIFF if it's not already open
+ // if( !tiff ){
+ // filename = getFileName( seq, ang );
+ // if( ( tiff = TIFFOpen( filename.c_str(), "r" ) ) == NULL ){
+ // throw string( "tiff open failed for:" + filename );
+ // }
+ // }
+
+ if(!osr){
+ filename = getFileName(seq, ang);
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "getTile\n");
+
+
+ fprintf(fp, "filename: %s\n", filename.c_str());
+
+ fclose(fp);
+
+
+ osr = openslide_open(filename.c_str());
+ if(osr ==NULL)
+ {
+ throw string("open slide open failed");
+ }
+ }
+
+ // Reload our image information in case the tile size etc is different
+ if( (currentX != seq) || (currentY != ang) ){
+ loadImageInfo( seq, ang );
+ }
+
+ int64_t big_w,big_h;
+
+ openslide_get_level0_dimensions(osr, &big_w, &big_h);
+
+ tw = 256;
+ th = 256;
+
+ // reduce size
+ im_width = (unsigned int)big_w;
+ im_height = (unsigned int)big_h;
+
+ fp = fopen("/tmp/iip.log", "a");
+
+ fprintf(fp, "LEVEL 0 dimension: im w * h: %d %d\n", im_width, im_height);
+
+ fclose(fp);
+
+ // // The first resolution is the highest, so we need to invert
+ // // the resolution - can avoid this if we store our images with
+ // // the smallest image first.
+ // int vipsres = ( numResolutions - 1 ) - res;
+
+ // // Change to the right directory for the resolution
+ // if( !TIFFSetDirectory( tiff, vipsres ) ) {
+ // throw string( "TIFFSetDirectory failed" );
+ // }
+
+ // // Check that a valid tile number was given
+ // if( tile >= TIFFNumberOfTiles( tiff ) ) {
+ // ostringstream tile_no;
+ // tile_no << "Asked for non-existant tile: " << tile;
+ // throw tile_no.str();
+ // }
+
+ // // Get the size of this tile, the current image,
+ // // the number of samples and the colourspace.
+ // // TIFFTAG_TILEWIDTH give us the values for the resolution,
+ // // not for the tile itself
+
+ // TIFFGetField( tiff, TIFFTAG_TILEWIDTH, &tw );
+ // TIFFGetField( tiff, TIFFTAG_TILELENGTH, &th );
+ // TIFFGetField( tiff, TIFFTAG_IMAGEWIDTH, &im_width );
+ // TIFFGetField( tiff, TIFFTAG_IMAGELENGTH, &im_height );
+ // TIFFGetField( tiff, TIFFTAG_PHOTOMETRIC, &colour );
+ // // TIFFGetField( tiff, TIFFTAG_SAMPLESPERPIXEL, &channels );
+ // // TIFFGetField( tiff, TIFFTAG_BITSPERSAMPLE, &bpp );
+
+
+ // Get the width and height for last row and column tiles
+ rem_x = im_width % tw;
+ rem_y = im_height % th;
+
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "getTile\n");
+ fprintf(fp, "remainder-> overhangs : rem_x rem_y: %d %d\n", rem_x, rem_y);
+
+ // Calculate the number of tiles in each direction
+ ntlx = (im_width / tw) + (rem_x == 0 ? 0 : 1);
+ ntly = (im_height / th) + (rem_y == 0 ? 0 : 1);
+
+ fprintf(fp, "rem_x rem_y: %d %d\n", ntlx, ntly);
+
+ // Alter the tile size if it's in the last column
+ if( ( tile % ntlx == ntlx - 1 ) && ( rem_x != 0 ) ) {
+ tw = rem_x;
+ }
+
+ // Alter the tile size if it's in the bottom row
+ if( ( tile / ntlx == ntly - 1 ) && rem_y != 0 ) {
+ th = rem_y;
+ }
+
+
+
+ fprintf(fp, "actual tile dimensions: %d %d\n", tw, th);
+ fclose(fp);
+
+
+
+
+
+ // // Handle various colour spaces
+ // if( colour == PHOTOMETRIC_CIELAB ) colourspace = CIELAB;
+ // else if( colour == PHOTOMETRIC_MINISBLACK ) colourspace = GREYSCALE;
+ // else if( colour == PHOTOMETRIC_PALETTE ){
+ // // Watch out for colourmapped images. There are stored as 1 sample per pixel,
+ // // but are decoded to 3 channels by libtiff, so declare them as sRGB
+ // colourspace = GREYSCALE;
+ // channels = 1;
+ // }
+ // else if( colour == PHOTOMETRIC_YCBCR ){
+ // // JPEG encoded tiles can be subsampled YCbCr encoded. Ask to decode these to RGB
+ // TIFFSetField( tiff, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
+ // colourspace = sRGB;
+ // }
+ // else
+ // colourspace = sRGB;
+
+
+ // // Allocate memory for our tile.
+ // if( !tile_buf ){
+ // if( ( tile_buf = _TIFFmalloc( TIFFTileSize(tiff) ) ) == NULL ){
+ // throw string( "tiff malloc tile failed" );
+ // }
+ // }
+
+ if(!osr_buf){
+
+ // stripe_buffer = new kdu_uint16[tw*stripe_heights[0]*channels];
+
+ osr_buf = new uint32_t[tw * th * 4];
+
+ // osr_buf = malloc(tw * th * 4);
+ if(osr_buf == NULL)
+ {
+ throw string("Openslide malloc failed");
+ }
+ }
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "buffer allocated successfully.\n", tw, th);
+ fclose(fp);
+
+
+ // calculate the location here from the seq + ang + tile? WTH
+ openslide_read_region(osr, osr_buf, 0, 0, 0, tw, th);
+
+
+
+ if (tw==256 && th==256) {
+
+ FILE *fp2;
+
+ char imagename[100];
+ sprintf(imagename, "/vagrant/%d-%d-%d-%d.ppm", seq, ang, res, tile);
+
+ fp2 = fopen(imagename, "w");
+ fprintf(fp2, "P6\n# Extraneous comment\n %d %d 255\n", tw, th);
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "P6\n# Extraneous comment\n %d %d 255\n", tw, th);
+ fclose(fp);
+
+ for (int y = 0; y < th; y++) {
+ for (int x = 0; x < tw; x++) {
+
+ uint32_t sample = osr_buf[y * th + x];
+
+ // undo premultiplication, more or less
+ double alpha = ((sample >> 24) ?: 1) / 255.0;
+
+ uint8_t pixel[3] = {
+ ((sample >> 16) & 0xff) / alpha,
+ ((sample >> 8) & 0xff) / alpha,
+ (sample & 0xff) / alpha,
+ };
+
+ fwrite(pixel, 1, sizeof(pixel), fp2);
+ }
+ }
+ fclose(fp2);
+ }
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "read openslide region.\n", tw, th);
+ fclose(fp);
+
+ // // Decode and read the tile
+ // int length = TIFFReadEncodedTile( tiff, (ttile_t) tile,
+ // tile_buf, (tsize_t) - 1 );
+ // if( length == -1 ) {
+ // throw string( "TIFFReadEncodedTile failed for " + getFileName( seq, ang ) );
+ // }
+
+
+ RawTile rawtile( tile, res, seq, ang, tw, th, channels, bpp );
+ rawtile.data = osr_buf;
+ rawtile.dataLength = tw*th*4;
+ rawtile.filename = getImagePath();
+ rawtile.timestamp = timestamp;
+ rawtile.memoryManaged = 0;
+ rawtile.padded = false;
+ rawtile.sampleType = sampleType;
+
+ fp = fopen("/tmp/iip.log", "a");
+ fprintf(fp, "created tile.\n", tw, th);
+ fclose(fp);
+
+
+ // RawTile rawtile = NULL;
+
+ return( rawtile );
+ // return 0;
+
+}
+
+// Get an entire region and not just a tile
+RawTile OpenSlideImage::getRegion( int seq, int ang, unsigned int res, int layers, int x, int y, unsigned int w, unsigned int h ) throw (string)
+{
+
+ logfile << "OpenSlideImage :: getRegion()" << endl;
+
+ // Scale up our output bit depth to the nearest factor of 8
+ unsigned int obpp = bpp;
+ if( bpp <= 16 && bpp > 8 ) obpp = 16;
+ else if( bpp <= 8 ) obpp = 8;
+
+ // FILE *fp;
+ // fp = fopen("/vagrant/getRegion.log", "w");
+
+ logfile << "OpenSlideImage :: bpp " << bpp << endl;
+ logfile << "OpenSlideImage :: xywh " << x << " " << y << " "<< w << " "<< h << " "<< res<< " " << layers << endl;
+
+ // fprintf(fp, "read region, bpp: %d.\n", bpp);
+ // fprintf(fp, "read region, xyhw,res,layers: %d %d %d %d %d %d\n", x,y,w,h,res, layers);
+
+ if(!osr_buf){
+ osr_buf = new uint32_t[w * h];
+ if(osr_buf == NULL)
+ {
+ throw string("Openslide malloc failed");
+ }
+ else{
+
+ logfile << "OpenSlideImage :: buffer allocated successfully: "<< (int)(w*h*4) <<" " << osr_buf[0] << endl;
+ }
+ }
+
+
+
+ openslide_read_region(osr, osr_buf, x, y, 0, w, h);
+
+ logfile << "OpenSlideImage :: buffer read successfully " << osr_buf[0] << endl;
+ logfile << "OpenSlideImage :: made tempbuf size of " << (int)(w*h*3) << endl;
+
+ FILE *fp2;
+ fp2 = fopen("/vagrant/testimage.ppm", "w");
+ fprintf(fp2, "P6\n# Extraneous comment\n %d %d 255\n", w, h);
+
+ uint8_t* tempbuf = new uint8_t[w*h*3];
+
+ int temp_index = 0;
+
+ logfile << "OpenSlideImage :: temp image written. " << temp_index << endl;
+
+
+ // need to write RGB as stripes across horizontal extent
+ // R1 R2 R3 R4
+ // G1 G2 G3 G4
+ // B1 B2 B3 B4
+
+ // r1 = (0,0,0
+ // r2 = (0,0,1)
+ // g1 = (0,0 )
+
+ int index = 0;
+ // for (int index = 0; index < w*h; ++index){
+
+ for (int j= 0; j < h; j++)
+ {
+ // int jstar = j*3;
+
+ for (int i = 0; i < w; i++)
+ {
+ uint32_t sample = osr_buf[j * w + i];
+
+ // int rowtotals = jstar*w;
+
+ index = j * w + i;
+
+ int istar = i*3;
+
+ int index2 = j * (w*3) + istar;
+
+ // uint32_t sample = osr_buf[index];
+
+ double alpha = ((sample >> 24) ?: 1) / 255.0;
+
+
+ uint8_t pixel[3] = {
+ ((sample >> 16) & 0xff) / alpha,
+ ((sample >> 8) & 0xff) / alpha,
+ (sample & 0xff) / alpha,
+ };
+
+ // if(index ==0)
+ // {
+ // logfile << alpha << " pix " << (int)pixel[0] << " " << (int)pixel[1] << " " << (int)pixel[2] << endl;
+ // }
+
+ // fwrite(pixel, 1, sizeof(pixel), fp2);
+
+ memcpy(&tempbuf[index2], pixel, 3);
+
+
+ // this writes a grid with channels RRR / GGG / BBB
+ // memcpy(&tempbuf[index], pixel, 1);
+ // memcpy(&tempbuf[index+(w*h)], pixel +1, 1);
+ // memcpy(&tempbuf[index+(w*h*2)], pixel +2, 1);
+
+
+
+ // memcpy(&tempbuf[rowtotals + i], pixel, 1);
+ // memcpy(&tempbuf[rowtotals + i + w], pixel+1, 1);
+ // memcpy(&tempbuf[rowtotals + i + 2*w], pixel+2, 1);
+
+
+ // memcpy(&tempbuf[temp_index+(2*w*h)], pixel[2], 1);
+ }
+ }
+
+ fclose(fp2);
+ logfile << "OpenSlideImage :: obpp is " << obpp << endl;
+
+ RawTile rawtile( 0, res, seq, ang, w, h, channels, obpp );
+
+ rawtile.data = tempbuf;
+ rawtile.dataLength = w*h*channels*obpp / 8 ;
+ rawtile.filename = getImagePath();
+ rawtile.timestamp = timestamp;
+ rawtile.memoryManaged = 0;
+ rawtile.padded = false;
+ rawtile.channels = 3;
+ rawtile.sampleType = sampleType;
+
+ logfile << "OpenSlideImage :: raw tile init okay " << endl;
+
+// #ifdef DEBUG
+ logfile << "OpenSlide :: completed read region" << endl;
+ //:: " << timer.getTime() << " microseconds" << endl;
+// #endif
+
+
+ return rawtile;
+
+}
+
+
View
143 src/OpenSlideImage.h
@@ -0,0 +1,143 @@
+// OpenSlideImage Image class Interface
+
+/* IIP OpenSlideImage Class
+
+ Derived from the Kakadu image wrapper
+ Copyright (C) 2009-2013 IIPImage.
+ Authors: Ruven Pillay & Petr Pridal
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+
+#ifndef _OPENSLIDEIMAGE_H
+#define _OPENSLIDEIMAGE_H
+
+#include "IIPImage.h"
+#include <iostream>
+#include <cstdio>
+#include <fstream>
+#include <openslide.h>
+
+// #include <tiff.h>
+// #include <tiffio.h>
+
+extern std::ofstream logfile;
+
+/// Image class for Tiled Pyramidal Images: Inherits from IIPImage. Uses libtiff
+class OpenSlideImage : public IIPImage {
+
+ private:
+
+ /// Pointer to the TIFF library struct
+ openslide_t *osr;
+ // TIFF *tiff;
+
+ /// Tile data buffer pointer
+ uint32_t *osr_buf;
+ // tdata_t tile_buf;
+
+ public:
+
+ /// Constructor
+ OpenSlideImage():IIPImage() {
+ osr = NULL; osr_buf = NULL;
+ };
+
+ /// Constructor
+ /** @param path image path
+ */
+ OpenSlideImage( const std::string& path ): IIPImage( path ) {
+ osr = NULL; osr_buf = NULL;
+ };
+
+ /// Copy Constructor
+ /** @param image IIPImage object
+ */
+ OpenSlideImage( const OpenSlideImage& image ): IIPImage( image ) {
+ osr = NULL; osr_buf = NULL;
+ };
+
+ /// Assignment Operator
+ /** @param OpenSlideImage object
+ */
+ OpenSlideImage& operator = ( const OpenSlideImage& image ) {
+ if( this != &image ){
+ closeImage();
+ IIPImage::operator=(image);
+ osr = image.osr;
+ osr_buf = image.osr_buf;
+ }
+
+ return *this;
+ }
+
+ /// Construct from an IIPImage object
+ /** @param image IIPImage object
+ */
+ OpenSlideImage( const IIPImage& image ): IIPImage( image ) {
+ osr = NULL; osr_buf = NULL;
+ };
+
+ /// Destructor
+ ~OpenSlideImage() { closeImage(); };
+
+ /// Overloaded function for opening a TIFF image
+ void openImage() throw (std::string);
+
+ /// Overloaded function for loading TIFF image information
+ /** @param x horizontal sequence angle
+ @param y vertical sequence angle
+ */
+ void loadImageInfo( int x, int y ) throw (std::string);
+
+ /// Overloaded function for closing a TIFF image
+ void closeImage();
+
+ /// Overloaded function for getting a particular tile
+ /** @param x horizontal sequence angle
+ @param y vertical sequence angle
+ @param r resolution
+ @param l quality layers
+ @param t tile number
+ */
+ RawTile getTile( int x, int y, unsigned int r, int l, unsigned int t ) throw (std::string);
+
+
+ // adding this means we bypass the tiling and pull straight from the Region
+ bool regionDecoding(){ return true; };
+
+ /// Overloaded function for returning a region for a given angle and resolution
+ /** Return a RawTile object: Overloaded by child class.
+ @param ha horizontal angle
+ @param va vertical angle
+ @param r resolution
+ @param l number of quality layers to decode
+ @param x x coordinate
+ @param y y coordinate
+ @param w width of region
+ @param h height of region
+ @param b buffer to fill
+ */
+ RawTile getRegion( int ha, int va, unsigned int r, int l, int x, int y, unsigned int w, unsigned int h ) throw (std::string);
+
+
+
+};
+
+
+
+
+#endif
Please sign in to comment.
Something went wrong with that request. Please try again.