robby
2017-10-3 12:19:05

@blerner @leif that’s a but in 2htdp/image (a library I maintain), but it is also a bug in pict:


robby
2017-10-3 12:21:28
#lang racket/base
(require file/convertible
         racket/class
         racket/gui/base)
(require (prefix-in p: pict))

(define bp
  (read-bitmap
   (open-input-bytes
    (convert (p:rectangle 0 0) 'png-bytes 'fallback))))

(send bp get-width) ;; ==> 1
(send bp get-height) ;; ==> 1

robby
2017-10-3 12:27:36

It isn’t obvious to me what the right behavior is here, but I’ve pushed a change that produces a 1x1 bitmap in that case


robby
2017-10-3 12:27:45

(but => bug)


robby
2017-10-3 12:44:15

@leif: you wrote earlier “it is probably a bug in the 2htdp library”; I just want to put out that the error message contains the line:


robby
2017-10-3 12:44:48
  blaming: <pkgs>/gui-lib/mrlib/image-core.rkt
   (assuming the contract is correct)

robby
2017-10-3 12:44:52

(lines)


leif
2017-10-3 12:58:00

Sure. I blamed 2htdp/image because pict didn’t fail. Although I personally thought making a 1x1 transparent png was the right thing to do here as apparently pngs can’t have a 0 width or height.


blerner
2017-10-3 12:58:34

Where is that speced? I couldn’t find that fact anywhere…


leif
2017-10-3 12:58:35

But yup, it was certainly the gui lib that tried to make the actual 0x0 picture. :slightly_smiling_face:


blerner
2017-10-3 13:00:58

Going back to a related question: do you happen to know how to ask a convertible what its width will be, if I try to convert it?


leif
2017-10-3 13:01:22

@blerner I honestly forget. Here is an unofficial SO answer while I track down the actual spec: https://stackoverflow.com/questions/7909212/how-to-create-empty-0x0-image


leif
2017-10-3 13:03:23

@blerner The closest thing that the convert library seems to support (by default) is: 'png-bytes+bounds, which gives you the width and height at the same time as converting the image.


leif
2017-10-3 13:04:35

You ‘could’ use 'png-bytes+bounds8, which automatically pads the png image.


leif
2017-10-3 13:05:02

This gives the effect of a 0x0 image being padded. And then it gives you the amount of padding added to each side.


blerner
2017-10-3 13:05:21

I tried that, and consistently got #f as my output. Looks like the snip doesn’t respond to that message


leif
2017-10-3 13:05:33

So in the case of (convert empty-image 'png-bytes+bounds8), you get a 6x6 sized png with 3 pixels of padding on the left, top, right, and bottom.


blerner
2017-10-3 13:05:39

Would be lovely if it did….


leif
2017-10-3 13:06:02

Ah, sad.


leif
2017-10-3 13:06:16

Then nope, I highly suspect it’s not possible. :confused:


blerner
2017-10-3 13:07:45

Png-bytes+bounds I can understand why it fails, since it promises to return the actual bytes and bounds, and can’t return a 0*0 image. But the padded version ought to work, and just doesn’t seem to be supported right now


leif
2017-10-3 13:08:32

Okay


leif
2017-10-3 13:08:36

I think I have a solution.


leif
2017-10-3 13:08:43

Its ugly and terrible, but….


leif
2017-10-3 13:08:48

convert to pdf-bytes.


leif
2017-10-3 13:09:03

Then use the racket-poppler package to get the width and height of the pdf page.


blerner
2017-10-3 13:09:27

Oh good grief. Srsly?


leif
2017-10-3 13:09:49

Ya, that is worse than just catching the exception. :disappointed:


blerner
2017-10-3 13:10:13

Well now thanks to Robby’s fix, there won’t be an exception to catch… Irony.


leif
2017-10-3 13:10:15

But ya, the convert library is kind of…lacking, imo.


blerner
2017-10-3 13:12:34

I wonder if the contract for png-bytes+bounds might not be better as (list (or/c bytes default) num num num num), instead of (or/c (list bytes num num num num) default)…


blerner
2017-10-3 13:13:21

In that you could get the bounds even if you couldn’t get the bytes


leif
2017-10-3 13:14:41

Eh, something you pass into the convert library might not even make sense to be a png file. In which case having it return default/c is the right thing.


leif
2017-10-3 13:15:02

What would be much better would be having a ‘width and ‘height convert targets.


blerner
2017-10-3 13:16:34

I can see efficiency reasons why that might not be ideal (eg if the image is recomputed each time, in order to measure it), but as an API that would be helpful


leif
2017-10-3 13:16:37

FYI, here is the png spec that makes a 0x0 png invalid: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html


leif
2017-10-3 13:17:14

I absolutely agree.


leif
2017-10-3 13:17:55

Honestly, I would just scrap the file/convert library altogether. Its a great idea, but its just too rigid in so many ways.


leif
2017-10-3 13:18:10

file/convertible*


blerner
2017-10-3 13:18:57

Well, it’s a nice trick that works with snips that I can’t statically predict what that are, so it’s got that going for it :-)


leif
2017-10-3 13:20:32

Sure. I think a convertiblity library absolutely must exist. Its just this particular instance which is too rigid.


leif
2017-10-3 13:20:50

I’ve actually been working on a replacement for use with video.


robby
2017-10-3 14:25:05

@blerner if you want to avoid catching the exception, you can check to see if the image has either a 0 width or a 0 height.


blerner
2017-10-3 14:25:41

Yesss, that’s exactly my question. I don’t have an image, I have a snip — how do I ask the snip for its dimensions, if I don’t know for certain that it’s an image-snip?


robby
2017-10-3 14:25:56

get-extent


robby
2017-10-3 14:26:24

but maybe non–2htdp/image snips don’t have this problem, so maybe you can get the image out?


blerner
2017-10-3 14:26:58

Currently, my code for this case is simply, [(convertible? snip) (let ((converted (with-handlers ([exn:fail:contract? (λ(e) 'conversion-failure)]) (convert snip 'png-bytes 'conversion-failure)))) (if (equal? converted 'conversion-failure) (display (add-empty-image "") out) (display (add-image (convert snip 'png-bytes)) out)))]


robby
2017-10-3 14:27:01

(I’ll note that image-snip% is an unrelated thing, which is slightly confusing to me at this point :slightly_smiling_face: )


blerner
2017-10-3 14:28:28

so I don’t have a dc<%> to give to (send a-snip get-extent dc x y). unless that’s not the get-extent you meant?


robby
2017-10-3 14:28:31

If you want to work around the bug, I suggest you check to see if the snip is actually an image? from 2htdp/image and if it has either a 0 width or a 0 height and then do the “conversion” yourself.


robby
2017-10-3 14:28:53

A bitmap dc would work fine for this purpose.


robby
2017-10-3 14:29:03

But that’s probably not the most direct approach


robby
2017-10-3 14:32:23

(If you want to stick with the code you have above, I suggest you use a regexp match on the error message so you don’t accidentally catch real bugs. I think that would also be just fine.)


blerner
2017-10-3 14:34:39

so using get-extent, it would be something like [(convertible? snip) (let* ((bm (new bitmap-dc%)) (width (box 0)) (height (box 0))) (send snip get-extent bm 0 0 width height) (if (or (= (unbox width) 0) (= (unbox height) 0)) (display (add-empty-image "") out) (display (add-image (convert snip 'png-bytes)) out)))] ?


robby
2017-10-3 14:35:24

I’m not sure what would go wrong exactly but you should probably put a 1x1 bitmap into the bitmap-dc.


robby
2017-10-3 14:36:16

(Also you don’t have to add an image to the html page when it is 0x0, right? You could just put something less? Maybe nothing?)


robby
2017-10-3 14:36:33

Also, you can use define in the rhs of a cond:


blerner
2017-10-3 14:36:51

right, that’s what the add-empty-image is doing; it’s letting me put a non-image placeholder into the resulting output


robby
2017-10-3 14:37:00
[(convertible? snip)
 (define bm (make-object bitmap-dc% (make-bitmap 1 1))))
 (define wb (box 0))
... etc

blerner
2017-10-3 14:38:05

good to know, thanks. I wasn’t certain about the scoping, so didn’t bother


robby
2017-10-3 14:39:54

It is scoped to that arm of the cond


robby
2017-10-3 14:40:06

(to the square brackets)


blerner
2017-10-3 14:44:01

yup, makes sense. I think I’d gotten so used to BSL that I forgot normal racket allows defines in places where they make sense :wink:


lexi.lambda
2017-10-3 21:36:06

@samth re: the GH issue, is racket7 easy to build these days? I haven’t tried it yet.


samth
2017-10-3 21:36:23

@lexi.lambda should be just make


lexi.lambda
2017-10-3 21:36:47

but how can I write Racket without DrRacket? :)


lexi.lambda
2017-10-3 21:39:24

oh, I see… racket7 does not imply racket-on-chez.


samth
2017-10-3 21:40:16

right


samth
2017-10-3 21:40:29

no need to miss out on DrRacket


samth
2017-10-3 21:40:31

:slightly_smiling_face:


lexi.lambda
2017-10-3 21:41:55

so I should just expect make base to give me an ordinary Racket installation with a slower and less buggy expander?


samth
2017-10-3 21:44:11

yes


samth
2017-10-3 21:44:21

and maybe a slower IO system


lexi.lambda
2017-10-3 21:48:04

exciting


samth
2017-10-3 21:54:16

you might want to build less than that


lexi.lambda
2017-10-3 21:56:24

if I want to install drracket, I don’t really have a choice, do I?


samth
2017-10-3 22:00:43

true


lexi.lambda
2017-10-3 22:01:33

I did notice that make base did not set up static-links into the pkgs/ dir… I don’t remember how those got set up in my normal from-source installation in the first place.


samth
2017-10-3 22:02:22

make sets them up for the pkgs that are in there


lexi.lambda
2017-10-3 22:03:19

okay. I seem to remember I stopped using make for some reason, but I don’t remember what the reason was.


lexi.lambda
2017-10-3 22:03:41

I think I wanted to not install the whole main-distribution.


lexi.lambda
2017-10-3 22:06:41

aww, my raco setup segfaulted.


samth
2017-10-3 22:11:25

if you can get a stack trace that would be a useful bug report


lexi.lambda
2017-10-3 22:19:16

@samth I have a crash report, but re-running raco setup worked. should I still open an issue?


samth
2017-10-3 22:19:27

Yes


lexi.lambda
2017-10-3 22:51:06

@samth Alex’s program still fails on the new expander


samth
2017-10-3 22:54:19

Worth reporting on the bug