The Inbox: Graphics-cmfcmf.407.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Graphics-cmfcmf.407.mcz

commits-2
A new version of Graphics was added to project The Inbox:
http://source.squeak.org/inbox/Graphics-cmfcmf.407.mcz

==================== Summary ====================

Name: Graphics-cmfcmf.407
Author: cmfcmf
Time: 28 May 2019, 11:08:38.38585 am
UUID: 02f1c0df-d0cd-4c46-a8bc-c2cd77ab3ed3
Ancestors: Graphics-mt.406

Send correct message when primitive fails (>>primitiveFailed instead of >>primitiveFail)

I found no other occurrences of >>primitiveFail in the image.

=============== Diff against Graphics-mt.406 ===============

Item was changed:
  ----- Method: Bitmap>>decompress:fromByteArray:at: (in category 'filing') -----
  decompress: bm fromByteArray: ba at: index
  "Decompress the body of a byteArray encoded by compressToByteArray (qv)...
  The format is simply a sequence of run-coded pairs, {N D}*.
  N is a run-length * 4 + data code.
  D, the data, depends on the data code...
  0 skip N words, D is absent
  (could be used to skip from one raster line to the next)
  1 N words with all 4 bytes = D (1 byte)
  2 N words all = D (4 bytes)
  3 N words follow in D (4N bytes)
  S and N are encoded as follows (see decodeIntFrom:)...
  0-223 0-223
  224-254 (0-30)*256 + next byte (0-7935)
  255 next 4 bytes"
  "NOTE:  If fed with garbage, this routine could read past the end of ba, but it should fail before writing past the ned of bm."
  | i code n anInt data end k pastEnd |
  <primitive: 'primitiveDecompressFromByteArray' module: 'MiscPrimitivePlugin'>
  <var: #bm type: 'int *'>
  <var: #ba type: 'unsigned char *'>
  <var: #anInt type: 'unsigned int'> "Force the type, otherwise it is inferred as unsigned char because assigned from ba"
  <var: #data type: 'unsigned int'>
  i := index.  "byteArray read index"
  end := ba size.
  k := 1.  "bitmap write index"
  pastEnd := bm size + 1.
  [i <= end] whileTrue:
  ["Decode next run start N"
  anInt := ba at: i.  i := i+1.
  anInt <= 223 ifFalse:
  [anInt <= 254
  ifTrue: [anInt := (anInt-224)*256 + (ba at: i).  i := i+1]
  ifFalse: [anInt := 0.
  1 to: 4 do: [:j | anInt := (anInt bitShift: 8) + (ba at: i).  i := i+1]]].
  n := anInt >> 2.
+ (k + n) > pastEnd ifTrue: [^ self primitiveFailed].
- (k + n) > pastEnd ifTrue: [^ self primitiveFail].
  code := anInt bitAnd: 3.
  code = 0 ifTrue: ["skip"].
  code = 1 ifTrue: ["n consecutive words of 4 bytes = the following byte"
  data := ba at: i.  i := i+1.
  data := data bitOr: (data bitShift: 8).
  data := data bitOr: (data bitShift: 16).
  1 to: n do: [:j | bm at: k put: data.  k := k+1]].
  code = 2 ifTrue: ["n consecutive words = 4 following bytes"
  data := 0.
  1 to: 4 do: [:j | data := (data bitShift: 8) bitOr: (ba at: i).  i := i+1].
  1 to: n do: [:j | bm at: k put: data.  k := k+1]].
  code = 3 ifTrue: ["n consecutive words from the data..."
  1 to: n do:
  [:m | data := 0.
  1 to: 4 do: [:j | data := (data bitShift: 8) bitOr: (ba at: i).  i := i+1].
  bm at: k put: data.  k := k+1]]]!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Graphics-cmfcmf.407.mcz

Nicolas Cellier
Usage of primitiveFail is on purpose here because this is the source code of the (misc) primitive.
So, it's an imperative style to make the primitive fail.

This is confusing if we run the primitive code as a fallback code
(we will run exact same code as primitive which is duplicating the work, if the primitive really exist, and will fail for same reasons).

I thought we got rid of those MiscprimitivePlugin.
We really should.

Le mar. 28 mai 2019 à 11:09, <[hidden email]> a écrit :
A new version of Graphics was added to project The Inbox:
http://source.squeak.org/inbox/Graphics-cmfcmf.407.mcz

==================== Summary ====================

Name: Graphics-cmfcmf.407
Author: cmfcmf
Time: 28 May 2019, 11:08:38.38585 am
UUID: 02f1c0df-d0cd-4c46-a8bc-c2cd77ab3ed3
Ancestors: Graphics-mt.406

Send correct message when primitive fails (>>primitiveFailed instead of >>primitiveFail)

I found no other occurrences of >>primitiveFail in the image.

=============== Diff against Graphics-mt.406 ===============

Item was changed:
  ----- Method: Bitmap>>decompress:fromByteArray:at: (in category 'filing') -----
  decompress: bm fromByteArray: ba at: index
        "Decompress the body of a byteArray encoded by compressToByteArray (qv)...
        The format is simply a sequence of run-coded pairs, {N D}*.
                N is a run-length * 4 + data code.
                D, the data, depends on the data code...
                        0       skip N words, D is absent
                                (could be used to skip from one raster line to the next)
                        1       N words with all 4 bytes = D (1 byte)
                        2       N words all = D (4 bytes)
                        3       N words follow in D (4N bytes)
                S and N are encoded as follows (see decodeIntFrom:)...
                        0-223   0-223
                        224-254 (0-30)*256 + next byte (0-7935)
                        255             next 4 bytes"   
        "NOTE:  If fed with garbage, this routine could read past the end of ba, but it should fail before writing past the ned of bm."
        | i code n anInt data end k pastEnd |
        <primitive: 'primitiveDecompressFromByteArray' module: 'MiscPrimitivePlugin'>
        <var: #bm type: 'int *'>
        <var: #ba type: 'unsigned char *'>
        <var: #anInt type: 'unsigned int'> "Force the type, otherwise it is inferred as unsigned char because assigned from ba"
        <var: #data type: 'unsigned int'>
        i := index.  "byteArray read index"
        end := ba size.
        k := 1.  "bitmap write index"
        pastEnd := bm size + 1.
        [i <= end] whileTrue:
                ["Decode next run start N"
                anInt := ba at: i.  i := i+1.
                anInt <= 223 ifFalse:
                        [anInt <= 254
                                ifTrue: [anInt := (anInt-224)*256 + (ba at: i).  i := i+1]
                                ifFalse: [anInt := 0.
                                                1 to: 4 do: [:j | anInt := (anInt bitShift: 8) + (ba at: i).  i := i+1]]].
                n := anInt >> 2.
+               (k + n) > pastEnd ifTrue: [^ self primitiveFailed].
-               (k + n) > pastEnd ifTrue: [^ self primitiveFail].
                code := anInt bitAnd: 3.
                code = 0 ifTrue: ["skip"].
                code = 1 ifTrue: ["n consecutive words of 4 bytes = the following byte"
                                                data := ba at: i.  i := i+1.
                                                data := data bitOr: (data bitShift: 8).
                                                data := data bitOr: (data bitShift: 16).
                                                1 to: n do: [:j | bm at: k put: data.  k := k+1]].
                code = 2 ifTrue: ["n consecutive words = 4 following bytes"
                                                data := 0.
                                                1 to: 4 do: [:j | data := (data bitShift: 8) bitOr: (ba at: i).  i := i+1].
                                                1 to: n do: [:j | bm at: k put: data.  k := k+1]].
                code = 3 ifTrue: ["n consecutive words from the data..."
                                                1 to: n do:
                                                        [:m | data := 0.
                                                        1 to: 4 do: [:j | data := (data bitShift: 8) bitOr: (ba at: i).  i := i+1].
                                                        bm at: k put: data.  k := k+1]]]!




Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Graphics-cmfcmf.407.mcz

cmfcmf
Nicolas Cellier wrote
> Usage of primitiveFail is on purpose here because this is the source code
> of the (misc) primitive.
> So, it's an imperative style to make the primitive fail.
>
> This is confusing if we run the primitive code as a fallback code
> (we will run exact same code as primitive which is duplicating the work,
> if
> the primitive really exist, and will fail for same reasons).

I see what you mean. It feels a bit like a chicken/egg problem.
I stumbled across this issue when I played around with decompressing Bitmaps
from ByteArrays and supplied data in the wrong format. Here's an example:

/Bitmap decompressFromByteArray: #[0 12]/

Currently, the primitive fails, then the Smalltalk code runs and calls the
non-existing (at least non-existing in the Smalltalk world)
/>>primitiveFail/ (like you described).

When I created the patch, I was not aware that the Smalltalk code is also
used to compile the primitive and that using />>primitiveFail/ is on
purpose.



--
Sent from: http://forum.world.st/Squeak-Dev-f45488.html