ruven / iipsrv

iipsrv is an advanced high-performance feature-rich image server for web-based streamed viewing and zooming of ultra high-resolution images.
https://iipimage.sourceforge.io
GNU General Public License v3.0
292 stars 115 forks source link

Full image loading without watermark #255

Open avnoorlogic opened 1 year ago

avnoorlogic commented 1 year ago

Hello everyone.

I set up IIP server on docker environment on apache server. Configured iipserver to show watermarks on images. But if I make request with http://my-domain/iiif/image-path/full/!1200,1500/0/default.jpg or http://my-domain/iiif/image-path/full/full/0/default.jpg parameters it load image without watermark. With this http://my-domain/iiif/image-path/8192,4096,1708,2344/107,/0/default.jpg parameter it will load proper way, with watermarks. If in parameters list is full parameter it will load image without watermarks. So my question is how to properly config iipserver to load images with watermark in those cases as well?

Thank you!

ruven commented 1 year ago

This works correctly with TIFF images, but not JPEG2000. For JPEG2000, there is currently a bug that prevents watermarking on non-tile regions. There's a fix here you could try: https://github.com/ruven/iipsrv/pull/219 So, the solution for now is either to try the above patch or switch to TIFF. For a permanent fix, I'm looking to restructure the code, but that won't be until after the release of version 1.2.

PS: I guess this almost identical question on sourceforge is from you also: https://sourceforge.net/p/iipimage/discussion/299494/thread/bc753733e0/?limit=25#9b72/1291

avnoorlogic commented 1 year ago

Hi @ruven ! Much appreciated your help. Yes it is exactly the same question. I see your point. But here the confusion is on the prod env with JP2000 image loading with watermarks with the full/full params works correctly. Can the issue be something else?

ruven commented 1 year ago

But here the confusion is on the prod env with JP2000 image loading with watermarks with the full/full params works correctly

Didn't you say that it was the full that doesn't work?

Essentially what happens is that when you request a "tile", the image goes through a pipeline where the image is decoded by the codec and immediately watermarked. For a "region", if the image is a TIFF, each tile is fetched individually and watermarked before being assembled into a mosaic. However, for JPEG2000, this mocaicking is handled directly by the codec itself and so is carried out outside of the watermarking pipeline.

avnoorlogic commented 1 year ago

@ruven Yes full doesn't work with watermarks. In production env, I can see something like this: Setting up JPEG2000 support via Kakadu SDK Setting Kakadu read-mode to fast Setting image processing engine to CPU processor OpenMP enabled for parallelized image processing with 4 threads Does it make sense?

ruven commented 1 year ago

Does it make sense?

Yes, it's behaving as expected.

rafayel7233 commented 1 year ago

hi @ruven .

thanks a lot for quick response and for the help. reinjecting myself to the discussion.

to sum up, our main issue as described above, is that on production the watermark works with full/full params correctly, i.e. you can see the full image with watermarks on it. However on the local and staging env it does not work.

So does this mean that in the production the solution with jpg2000 was done using kakadu SDK?.

As I understand correctly, the solution was done using kakadu sdk. since you are telling that currently there is an issue with jpg 2000. so in case of the full image the issue was handled directly by the codec itself i.e. carried out outside of the watermarking pipeline?

Please let me know if I missed smth.

Thanks again Rafael

ruven commented 1 year ago

@rafayel7233 and @avnoorlogic your messages are rather contradictory. Can you please clarify? @avnoorlogic is saying that full images do not work and that tiles do. But @rafayel7233 you are now saying that full does work, but only on the production machine.

Full images will never work with JPEG2000, unless the image is small enough to be considered a tile (ie. smaller than the tile size of 256 pixels). Anything larger will not be watermarked.

rafayel7233 commented 1 year ago

@ruven sorry for confusion, let me clarify.

Production.

in the production env. we have images with the following params. /768,1536,256,256/256,/0/default.jpg. this opens a small part of the whole image, with watermark on it. as you also confirmed, the size is smaller then 256 pixels. On the other hand, we have also /full/full params, which opens the full image, the resolution of which seems to be the original image, at least it is greater than 256 pixels a couple of times. However in the production env we can see the watermark on it either. I am not sure how it is done, but we can see the full image with watermarks on it.

Staging/Local in the staging env with the following params. /768,1536,256,256/256,/0/default.jpg we can get the watermark on the small images (image particles). However, when opening the full image with full/full the watermark is not on it.

We noticed one thing though, it seems that in case of full/full jpg format, when we download the image, it seems not to be the same quality then the original image when we compare (we have the original image) - the size is small and resolution is different. might it be the case that when opening via full/full it is not showing the original image, or smth constructed vial tiles? or might it be smth else?

Thanks in advance.

Rafael

ruven commented 1 year ago

when we download the image, it seems not to be the same quality then the original image when we compare (we have the original image)

The output images are transcoded to the output format you ask for (JPEG in this case). Remember that your source image is a JPEG2000 image, so transcoding needs to happen. You can, however, modify the JPEG quality factor for the output image. It's set to 75 by default, but you can use the JPEG_QUALITY startup variable to set it higher if you want better quality.

As for the difference between your environments, it indeed seems strange that this should happen. I presume your iipsrv startup variables are identical? What about the WATERMARK_PROBABILITY parameter. If this is not set to 1, then watermarks will be applied randomly. Could this explain the differences?

avnoorlogic commented 1 year ago

@ruven On local env WATERMARK_PROBABILITY=1.0 and JPEG_QUALITY=50. On live env WATERMARK_PROBABILITY=1.0 and JPEGQUALITY=90. What do you mean by ' I presume your iipsrv startup variables are identical? '_. Which startup variables do you mean? Thanks!

ruven commented 1 year ago

I was indeed referring to variables like JPEG_QUALITY, WATERMARK_PROBABILITY, VERBOSITY and LOGFILE etc that you supply to iipsrv.

If WATERMARK_PROBABILITY is set to 1.0 on both your production and staging servers, the output should be identical. Can you give me an example IIIF URL where you see the watermark in the production server but not the staging one? Give me also the exact image size of the JPEG2000 being requested.

What about Memcached? Are you using a shared cache?

avnoorlogic commented 1 year ago

@ruven I wont be able to share staging and production environment image urls. Can share some part of my configuration file if it makes sence. VERBOSITY on staging is 10, on prodaction is 1 Thanks

ruven commented 1 year ago

I wont be able to share staging and production environment image urls

Not the whole URL, just the IIIF part after the image name

avnoorlogic commented 1 year ago

@ruven Here is the url /iiif/na/na/0042/00001300/NA.0042.00001308.jp2/full/full/0/default.jpg that for stagig env loads without watermarks but for production loads with watermarks

ruven commented 1 year ago

And what is the size in pixels of this JPEG2000 image?

avnoorlogic commented 1 year ago

@ruven 1480 X 1000

ruven commented 1 year ago

OK, and can you copy and paste what it prints in the iipsrv log on the staging server when you make this request (so not all the log, just the lines relevant to this request)?

avnoorlogic commented 1 year ago

@ruven yes image

avnoorlogic commented 1 year ago

@ruven also after a while I am getting this log message. image

ruven commented 1 year ago

For your first log extract, this is just sending a HTTP 304 with your browser using its cached version. Try doing a shift reload to get it to fully extract the image.

For the terminated signal shutdown. Is this happening by itself or are you triggering a shutdown? You also seem to have multiple instances of iipsrv running. Switch to just 1 for debugging purposes.

avnoorlogic commented 1 year ago

@ruven `CVT :: Compressed data strip length is 16377 CVT :: About to compress strip with height 104 CVT :: Compressed data strip length is 15774 CVT :: Total command time 564370 microseconds IIIF :: Total command time 564717 microseconds Memcached :: stored 117935 bytes in 15 microseconds Total Request Time: 565100 microseconds image closed and deleted Server count is 3

Full Request is iiif=na/na/0042/00001300/NA.0042.00001308.jp2/full/full/0/default.jpg [1/1]: Command / Argument is iiif : na/na/0042/00001300/NA.0042.00001308.jp2/full/full/0/default.jpg IIIF handler reached IIIF :: URL decoded to na/na/0042/00001300/NA.0042.00001308.jp2/full/full/0/default.jpg FIF handler reached FIF :: URL decoding/filtering: na/na/0042/00001300/NA.0042.00001308.jp2 => na/na/0042/00001300/NA.0042.00001308.jp2 FIF :: Image cache hit. Number of elements: 1 FIF :: JPEG2000 image detected FIF :: Created image FIF :: Image dimensions are 1480 x 1000 FIF :: Image contains 3 channels with 8 bits per channel FIF :: Image timestamp: Thu, 13 Apr 2023 14:13:56 GMT FIF :: Total command time 245 microseconds IIIF :: Requested Region: x:0, y:0, w:1, h:1 IIIF :: Requested Size: 1480x1000 IIIF :: Requested Rotation: 0 degrees IIIF :: Requested Quality: default with format: jpg IIIF :: image request for na/na/0042/00001300/NA.0042.00001308.jp2 with arguments: region: 0,0,1480,1000; size: 1480x1000; rotation: 0; mirroring: 0 CVT handler reached CVT :: Using resolution 3 with size 1480x1000 CVT :: No view port set CVT :: Requested scaled region size is 1480x1000. Nearest existing resolution is 3 which has region with size 1480x1000 TileManager getRegion :: requesting region directly from image CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 10065 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 10356 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 10883 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 18696 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 18269 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 17277 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 16377 CVT :: About to compress strip with height 104 CVT :: Compressed data strip length is 15774 CVT :: Total command time 559728 microseconds IIIF :: Total command time 560066 microseconds Memcached :: stored 117935 bytes in 14 microseconds Total Request Time: 560504 microseconds image closed and deleted Server count is 4 `

avnoorlogic commented 1 year ago

Shut down is happening by itself

ruven commented 1 year ago

OK, so can you now increase the verbosity on your production machine and do the exact same request?

And how are you starting the iipsrv instance? Through Apache? On the command line?

avnoorlogic commented 1 year ago

@ruven I have docker container with apache and iipsrv. services I am starting by container run.

avnoorlogic commented 1 year ago

@ruven for prodaction logs I need a high level permission, so today won't be. Also when I am loading image by tails and watermarks are appeared on the images I am getting this log message

`

Full Request is iiif=na/na/0042/00001300/NA.0042.00001308.jp2/1024,0,456,512/228,/0/default.jpg [1/1]: Command / Argument is iiif : na/na/0042/00001300/NA.0042.00001308.jp2/1024,0,456,512/228,/0/default.jpg IIIF handler reached IIIF :: URL decoded to na/na/0042/00001300/NA.0042.00001308.jp2/1024,0,456,512/228,/0/default.jpg FIF handler reached FIF :: URL decoding/filtering: na/na/0042/00001300/NA.0042.00001308.jp2 => na/na/0042/00001300/NA.0042.00001308.jp2 FIF :: Image cache initialization FIF :: JPEG2000 image detected FIF :: Created image FIF :: Image dimensions are 1480 x 1000 FIF :: Image contains 3 channels with 8 bits per channel FIF :: Image timestamp: Thu, 13 Apr 2023 14:13:56 GMT FIF :: Total command time 315 microseconds IIIF :: Requested Region: x:1024, y:0, w:456, h:512 IIIF :: Requested Size: 228x256 IIIF :: Requested Rotation: 0 degrees IIIF :: Requested Quality: default with format: jpg IIIF :: image request for na/na/0042/00001300/NA.0042.00001308.jp2 with arguments: region: 1024,0,456,512; size: 228x256; rotation: 0; mirroring: 0 CVT handler reached CVT :: Using resolution 2 with size 740x500 CVT :: Region: 512,0,228,256 CVT :: Requested scaled region size is 228x256. Nearest existing resolution is 2 which has region with size 228x256 TileManager getRegion :: requesting region directly from image CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 2548 CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 2905 CVT :: Total command time 93763 microseconds IIIF :: Total command time 94171 microseconds Memcached :: stored 5687 bytes in 15 microseconds Total Request Time: 94730 microseconds image closed and deleted Server count is 1

TileManager :: Watermark applied: 83 microseconds TileManager :: JPEG Compression Time: 381 microseconds TileManager :: Tile cache insertion time: 8 microseconds TileManager :: Total Tile Access Time: 196529 microseconds JTL :: Tile size: 256 x 256 JTL :: Channels per sample: 3 JTL :: Bits per channel: 8 JTL :: Data size is 6465 bytes JTL :: Total command time 196568 microseconds IIIF :: Total command time 196962 microseconds Memcached :: stored 6635 bytes in 14 microseconds Total Request Time: 197486 microseconds image closed and deleted Server count is 1

TileManager :: Watermark applied: 97 microseconds TileManager :: JPEG Compression Time: 387 microseconds TileManager :: Tile cache insertion time: 8 microseconds TileManager :: Total Tile Access Time: 308407 microseconds JTL :: Tile size: 256 x 256 JTL :: Channels per sample: 3 JTL :: Bits per channel: 8 JTL :: Data size is 6071 bytes JTL :: Total command time 308448 microseconds IIIF :: Total command time 309315 microseconds Memcached :: stored 6241 bytes in 13 microseconds Total Request Time: 310344 microseconds image closed and deleted Server count is 1

CVT :: About to compress strip with height 128 CVT :: Compressed data strip length is 4401 CVT :: About to compress strip with height 116 CVT :: Compressed data strip length is 4907 CVT :: Total command time 270016 microseconds IIIF :: Total command time 270825 microseconds Memcached :: stored 9545 bytes in 21 microseconds Total Request Time: 271727 microseconds image closed and deleted Server count is 1

Caught Terminated signal. Terminating after 1 accesses Caught Terminated signal. Terminating after 1 accesses Caught Terminated signal. Terminating after 1 accesses Caught Terminated signal. Terminating after 1 accesses Caught Terminated signal. Terminating after 5 accesses Thu Apr 13 15:16:55 2023 Thu Apr 13 15:16:55 2023 Thu Apr 13 15:16:55 2023 Thu Apr 13 15:16:55 2023 Thu Apr 13 15:16:55 2023 <-----------------------------------> <-----------------------------------> <-----------------------------------> <-----------------------------------> <----------------------------------->

`

ruven commented 1 year ago

Yes, this line indicates that watermarking is occurring for some of your requests:

TileManager :: Watermark applied: 83 microseconds

However, for the other request 1024,0,456,512/228,/0/default.jpg watermarking doesn't occur.

Watch out: as you are starting multiple iipsrv instances, the various instances are printing their logs to the same file making it difficult to trace properly.

avnoorlogic commented 1 year ago

@ruven thanks for your answer How can I check iipsrv instances?

ruven commented 1 year ago

How can I check iipsrv instances?

You said you're using Apache, so to start just 1 instance, set FcgidMaxProcessesPerClass 1 in the Apache config file where you configure FCGI and iipsrv.

avnoorlogic commented 1 year ago

@ruven Oh, In my case it is set 80

    FcgidMaxRequestLen 1073741824
    FcgidOutputBufferSize 1073741824
    FcgidMinProcessesPerClass 0
    FcgidMaxRequestsPerProcess 0
    FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 0
    FcgidInitialEnv PHP_FCGI_CHILDREN 0
    FcgidMaxProcessesPerClass 80
    FcgidIdleTimeout 120
    FcgidBusyTimeout  300
    FcgidProcessLifeTime 300
    FcgidIOTimeout 300
    FcgidInitialEnv URI_MAP "iiif=>IIIF"
ruven commented 1 year ago

80 is rather high! Unless you have an 80-core CPU of course ;-)

avnoorlogic commented 1 year ago

Hi @ruven . Hope you are going well.

I am trying to install Kakadu with IIpsrvc but getting errors

In file included from KakaduImage.cc:29:0: KakaduImage.h:38:10: fatal error: jpx.h: No such file or directory

include

^~~ compilation terminated. Makefile:475: recipe for target 'KakaduImage.o' failed make[1]: *** [KakaduImage.o] Error 1 make[1]: Leaving directory '/opt/iipsrv/src'

How can I fix this?

ruven commented 1 year ago

You need to let iipsrv know where your Kakadu source files are at the initial ./configure step before building with make. For example:

./configure --with-kakadu=/path/to/v8_3-XXX

You should see Kakadu listed as enabled at the end.

avnoorlogic commented 1 year ago

@ruven I am running this command on my docker container

chmod +x configure && sleep 2 && ./configure --enable-jp2 --with-kakadu=/usr/local/Kakadu && sleep 2 && make && make install

avnoorlogic commented 1 year ago

And kakadu I am downloading form this source http://kakadusoftware.com/wp-content/uploads/KDU805_Demo_Apps_for_Linux-x86-64_200602.zip

ruven commented 1 year ago

Your link is just for binary executables - you need the Kakadu SDK. Kakadu's software is proprietary and you will need to contact Kakadu to purchase a license for the SDK.

avnoorlogic commented 1 year ago

Got it. Thank you!

avnoorlogic commented 1 year ago

@ruven If I set up Kakadu instead of OpenJPG, Will it solve the issue related to full image watermarking or the issue related to only JPEG2000 format?

ruven commented 1 year ago

If I set up Kakadu instead of OpenJPG, Will it solve the issue related to full image watermarking or the issue related to only JPEG2000 format?

No, the issue is related to JPEG2000 in general

avnoorlogic commented 1 year ago

Can you suggest any solution that can solve this issue? Because missing watermarks on full images are a policy issue.

ruven commented 1 year ago

Can you suggest any solution that can solve this issue?

If you want an immediate solution, there are 2 options:

  1. Switch to using TIFF or
  2. As mentioned earlier, this fork fixes your problem: https://github.com/Cogapp/iipsrv/tree/cvtwatermarking
avnoorlogic commented 1 year ago

@ruven thanks a lot for the solution. I have tried 2nd option and it worked.