Hiding information in Cats
Mathematica, 255 234 206 bytes

I've seen so many 255s while testing this, I'm unreasonably happy about the size of the code. :) And then my ambition to golf it down even further got the best of me...

f=(j=ImageData[Import@#2,t="Byte"];k=(d=IntegerDigits)[j,2,8]~Flatten~2;n=1;(k[[n++,-1]]=#)&amp;/@d[Length@#,2,24]~Join~#&amp;[Join@@d[ToCharacterCode@#,2,8]];ArrayReshape[#~FromDigits~2&amp;/@k,Dimensions@j]~Image~t)&amp;


It's technically a function and not a "program", but then again this is pretty much how you write "programs" in Mathematica, if that concept is even valid there. Call it like

f["my secret", "fully/qualified/cat.png"]


It will return an actual image expression (because that's the most natural way to return an image in Mathematica), so if you want a file, you need to export it:

Export["output-cat.png", f["my secret", "input-cat.png"]]


Here is the required example:



I'd love to show you the decoded message here, but it doesn't fit... so run it through the OP's decoder. ;)

Btw, I could make it work with UTF-8 secrets for just 7 bytes (change ToCharacterCode@# into #~ToCharacterCode~"utf8").

Ungolfed code:

f[secret_, filename_] := (
  bits = Join @@ IntegerDigits[ToCharacterCode[secret], 2, 8];
  bits = Join[d[Length @ bits, 2, 24], bits];
  data = ImageData[Import@#2, "Byte"];
  dims = Dimensions@data;
  data = Flatten[IntegerDigits[data, 2, 8], 2];
  m = n = 1;
  While[m &lt;= Length @ bits,
    data[[n++, -1]] = bits[[m++]]
  ];
  Image[ArrayReshape[FromDigits[#, 2] &amp; /@ data, dims], "Byte"]
)