• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

How to protect assets?

ddabrahim

Active member
Tutorial Author
Joined
May 3, 2020
Messages
289
Hi.

After I build a desktop application, assets like images, sounds and fonts can be easily extracted from the build.
Is there anyway I can protect these assets, encrypt them?

I don't personally mind, I am "open minded" and I agree the only thing can truly protect the assets is a license included with them.
However, most people freak out when they can see their assets accessible as easily as opening a folder. Is there anyway to please them?

Thank you in advance.
 
Not with Cerberus directly.
Commercial applications will either store assets internally, i.e. embedded, use a custom virtual file system or custom file format.
Encryption is usually pointless as the data could be extracted from memory once it's decoded.
 
Last edited:
So, even put it in to a password protected zip or something is not an option with Cerberus?
That's unfortunate.

Yes I know things can be accessed in memory after decode but nobody needs to know that if not asking. I am talking about people who only care not to be able to see the assets and open it in 3rd party tools like image editors 😁
 
You can create resources like images internally.
 

Attachments

  • creategraphicsOnCreate.cxs.zip
    2 KB · Views: 69
Interesting, looks like it is what I am after. But how did you get this sprite information that you used to create the images from? Is there any tool I can use to get this info from any image?

Thanks.
 
It's not my example so I'm not sure how that person got that in there. You need to have ambition I guess :oops:. Probably some custom procedure, it can be anything as long as it works.

This was just meant for inspiration to see what can be done for all files even images.

I'm trying to do the same for wav files right now.
 
Be warned that embedding image data into your applications will have big disadvantages in application size and memory use.
 
But how did you get this sprite information that you used to create the images from?
I very much doubt that there will be an application for that.
When it comes to converting image for embedding into applications. There are three main ways.
  • Precompile to object code using a resource compiler and linking into the application.
    • This requires that you a reference pointer to each assets data.
  • Use a dedicated converter to translate the image into C code.
    • A note here is that the XPM format is actually C code to begin with.
  • Hand code your own images byte by byte.
 
Be warned that embedding image data into your applications will have big disadvantages in application size and memory use.

I was thinking if I store the image data inside an array and then initialise the array only when needed and empty the array when I don't, then it is going to allocate the memory only when I use it and free up when I don't. Would it be not the case?

When it comes to converting image for embedding into applications. There are three main ways.

What I was thinking is maybe I could write a converter to get the color and alpha value of every single pixel of an image and store that inside an Array in Cerberus and then reconstruct the image from this array, pixel by pixel on to a new canvas maybe and create an image from the canvas and finally draw the image on to the screen. But I don't know if it makes sense or is it practical.
 
I was thinking if I store the image data inside an array and then initialise the array only when needed and empty the array when I don't, then it is going to allocate the memory only when I use it and free up when I don't. Would it be not the case?
Doesn't work like that. When you embed an image into the application as an array, then data is already there. All you do is read the data to a screen buffer or image to display.

What I was thinking is maybe I could write a converter to get the color and alpha value of every single pixel of an image and store that inside an Array in Cerberus and then reconstruct the image from this array, pixel by pixel on to a new canvas maybe and create an image from the canvas and finally draw the image on to the screen. But I don't know if it makes sense or is it practical.
A more easier solution would be to use a third part tool such as png2c to convert the image into raw C/C++ data and then to write a converter that reads this file to your own custom binary file format that you would read in via FileStream.

Here's an example of an embedded png image.
It should be noted that the array is not optimised as each element will be 32 bits long, thus using more memory.
 

Attachments

  • embedded_001.zip
    25.6 KB · Views: 75
Last edited:
Thank you for the explanation, the png2c converter is definately useful, I'll see what I can do with it. Probably not much, but I'll try 😁
 
Thanks, really appreciate it. By looking at the code, I thought it is the same that Jimmy has shared. I'll take an other look then.
 
Another tool for converting images is 'convert'. This is found as part of the ImageMagick package.
Unfortunately, it doesn't output image information when converting to C-Style headers. But it can convert images to uncompressed NetPBM, in particular the PAM format. Which is very easy to parse and read data from.
 
I hate to see external utilities used when the problem is so simple.

This is half-baked conssideration but it will get you started I think. It reads the image into an array. You just have to write the numbers to a file and paste it into the source, but you must be careful when you change the size and consider handling the width and height correctly. It's not hard but it's easy to make a mistake.

The example will read a specific size in this instance we'll use 320x200, pixels into exacyly 64000 numbers in an array.
Ready to be written as sourcematerial for the loader given at the top.

This is how the creator might've created the using Cerberus-X itself.

⭐ This is my suggestion what to use as a base even if it takes a second or two, and on top of this you only need to write the values to a file and paste into the first source in this thread, and make sure that the width and height is correctly handled.

Code:
Strict
Import mojo2
Import brl.databuffer

Function Main:Int()
    New Game
    Return 0
End

Class Game Extends App

    Field storage:Int[320*200]
    Field xxx:Int, yyy:Int,screen2:Image, sprite:Canvas, canvas:Canvas
    Field pixels:DataBuffer = New DataBuffer(4*320*200), ptr:Int = 0, sourceImage:Image
    Field starter:Int = 0
 
    Method OnCreate:Int()
        canvas=New Canvas
        SetSwapInterval 1 ; SetUpdateRate 0
        sourceImage = Image.Load("screen.png",0,0,0)
        screen2=New Image(320,200,0,0,0)
        sprite=New Canvas(screen2)
        Return 0
    End

    Method OnRender:Int()
            canvas.Clear 0,0,0,0
        If starter < 10
            starter = starter + 1
            If starter > 5 Then sprite.DrawImage sourceImage,0,0
        Endif
        For Local temp:Int = 0 To 99 '  Read  only 100 pixels per frame as we do not want hold up any frames
            yyy = Int(ptr/320) ; xxx = ptr-(yyy*320) ; ptr = ptr + 1
   
         ' Not finished yet so keep reading pixels
        if ptr =< (320*200)
                 sprite.ReadPixels(xxx,yyy,1,1, pixels) ' read just one pixel
                 storage[ptr] = pixels.PeekInt(0)
       Endif
 
       ' Finished!
       If ptr > (320*200)
             ptr = 0
            ' Finished reading the whole image into storage[], ready to write a file and quit!
         Endif
   
        Next
        sprite.Flush
        canvas.DrawImage screen2.0.0
        canvas.Flush
        Return 0
    End
End
 
Last edited:
This is how you would read all pixels at once, everything in one frame, If we hoped that ONE frame had enough time for all our computation needs. It's simple but not always doable, the other one can do 8K no problem.
Code:
Strict
Import mojo2
Import brl.databuffer

Function Main:Int()
New Game
Return 0
End

Class Game Extends App

Field storage:Int[320*200]
Field xxx:Int, yyy:Int
Field screen2:Image
Field sprite:Canvas
Field canvas:Canvas
Field pixels:DataBuffer = New DataBuffer(4*320*200)
Field sourceImage:Image
Field starter:Int = 0

Method OnCreate:Int() 
canvas=New Canvas
SetSwapInterval 1 ; SetUpdateRate 0
sourceImage = Image.Load("screen.png",0,0,0)
screen2=New Image(320,200,0,0,0)
sprite=New Canvas(screen2)

Return 0
End

Method OnRender:Int()
canvas.Clear

' Trick To get html5 working
' (as we cannot draw in OnCreate or inside OnRender during the first few frames as a HTML5-target)
If starter < 10
starter = starter + 1
If starter > 5
sprite.DrawImage sourceImage,0,0 ; sprite.Flush ' For non-HTML5 platforms you could just stick this line in the OnCreate and forget about this trick
Endif
Endif

' We know that Sprite contains the image now, so let's read it:
If starter = 10
starter = 11
' Lets imagine we have infinite time in one frame and be bold enough to read all the pixels in one go!
sprite.ReadPixels(0,0,320,200, pixels) ' This is the only command that might take time. But big sizes takes a lot of time and boy can it ruin your dayplan.
For Local temp:Int = 0 To 63999
yyy = Int(temp/320) ; xxx = temp-(yyy*320)
storage[temp] = pixels.PeekInt(Int(Int(xxx)*4+Int(yyy)*320*4))
Next
' Save the array into file here
'
Endif

' Just draw what we are doing on the screen, this does nothing important
canvas.DrawImage screen2,0,0
canvas.Flush
Return 0
End


End
 
Last edited:
This is the only way I know to get the pixels inside Cerberus-X.
I don't know a way to readpixels outside of OnRender but someone else might have a better solution for that. (y)

It works fine. But inside OnRender.. if you are reading pixels.. you have the spotlight on you and you better be quick.
 
You could jumble images and reconstruct them after loading. If the image is present in chunks just with pieces moved or channels swapped, it would allow you to take advantage of optimised graphics encoding so your assets stay small. (Converting your graphics into big wodges of encrypted data will mean the file size will grow enormously).
 
Back
Top Bottom