func splitToBytes(x uint32) (one, two, three, four byte) {
	one = byte(x >> 24)
	var mask uint32 = 255
	two = byte((x >> 16) & mask)
	three = byte((x >> 8) & mask)
	four = byte(x & mask)
	return
}
splitToBytes given an unsigned integer, will split this integer into its four bytes
package steganography
import (
	"bytes"
	"errors"
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
)
func EncodeNRGBA(writeBuffer *bytes.Buffer, rgbImage *image.NRGBA, message []byte) error {
	var messageLength = uint32(len(message))
	var width = rgbImage.Bounds().Dx()
	var height = rgbImage.Bounds().Dy()
	var c color.NRGBA
	var bit byte
	var ok bool
	if MaxEncodeSize(rgbImage) < messageLength+4 {
		return errors.New("message too large for image")
	}
	one, two, three, four := splitToBytes(messageLength)
	message = append([]byte{four}, message...)
	message = append([]byte{three}, message...)
	message = append([]byte{two}, message...)
	message = append([]byte{one}, message...)
	ch := make(chan byte, 100)
	go getNextBitFromString(message, ch)
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			c = rgbImage.NRGBAAt(x, y)  
			bit, ok = <-ch
			if !ok {  
				rgbImage.SetNRGBA(x, y, c)
				png.Encode(writeBuffer, rgbImage)
			}
			setLSB(&c.R, bit)
			bit, ok = <-ch
			if !ok {
				rgbImage.SetNRGBA(x, y, c)
				png.Encode(writeBuffer, rgbImage)
				return nil
			}
			setLSB(&c.G, bit)
			bit, ok = <-ch
			if !ok {
				rgbImage.SetNRGBA(x, y, c)
				png.Encode(writeBuffer, rgbImage)
				return nil
			}
			setLSB(&c.B, bit)
			rgbImage.SetNRGBA(x, y, c)
		}
	}
	err := png.Encode(writeBuffer, rgbImage)
	fmt.Println("err")
	return err
}
func Encode(writeBuffer *bytes.Buffer, pictureInputFile image.Image, message []byte) error {
	rgbImage := imageToNRGBA(pictureInputFile)
	return EncodeNRGBA(writeBuffer, rgbImage, message)
}
func decodeNRGBA(startOffset uint32, msgLen uint32, rgbImage *image.NRGBA) (message []byte) {
	var byteIndex uint32
	var bitIndex uint32
	width := rgbImage.Bounds().Dx()
	height := rgbImage.Bounds().Dy()
	var c color.NRGBA
	var lsb byte
	message = append(message, 0)
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			c = rgbImage.NRGBAAt(x, y)  
			lsb = getLSB(c.R)                                                     
			message[byteIndex] = setBitInByte(message[byteIndex], bitIndex, lsb)  
			bitIndex++
			if bitIndex > 7 {  
				bitIndex = 0
				byteIndex++
				if byteIndex >= msgLen+startOffset {
					return message[startOffset : msgLen+startOffset]
				}
				message = append(message, 0)
			}
			lsb = getLSB(c.G)
			message[byteIndex] = setBitInByte(message[byteIndex], bitIndex, lsb)
			bitIndex++
			if bitIndex > 7 {
				bitIndex = 0
				byteIndex++
				if byteIndex >= msgLen+startOffset {
					return message[startOffset : msgLen+startOffset]
				}
				message = append(message, 0)
			}
			lsb = getLSB(c.B)
			message[byteIndex] = setBitInByte(message[byteIndex], bitIndex, lsb)
			bitIndex++
			if bitIndex > 7 {
				bitIndex = 0
				byteIndex++
				if byteIndex >= msgLen+startOffset {
					return message[startOffset : msgLen+startOffset]
				}
				message = append(message, 0)
			}
		}
	}
	return
}
func decode(startOffset uint32, msgLen uint32, pictureInputFile image.Image) (message []byte) {
	rgbImage := imageToNRGBA(pictureInputFile)
	return decodeNRGBA(startOffset, msgLen, rgbImage)
}
func Decode(msgLen uint32, pictureInputFile image.Image) (message []byte) {
	return decode(4, msgLen, pictureInputFile)  
}
func MaxEncodeSize(img image.Image) uint32 {
	width := img.Bounds().Dx()
	height := img.Bounds().Dy()
	eval := ((width * height * 3) / 8) - 4
	if eval < 4 {
		eval = 0
	}
	return uint32(eval)
}
func GetMessageSizeFromImage(pictureInputFile image.Image) (size uint32) {
	sizeAsByteArray := decode(0, 4, pictureInputFile)
	size = combineToInt(sizeAsByteArray[0], sizeAsByteArray[1], sizeAsByteArray[2], sizeAsByteArray[3])
	return
}
func getNextBitFromString(byteArray []byte, ch chan byte) {
	var offsetInBytes int
	var offsetInBitsIntoByte int
	var choiceByte byte
	lenOfString := len(byteArray)
	for {
		if offsetInBytes >= lenOfString {
			close(ch)
			return
		}
		choiceByte = byteArray[offsetInBytes]
		ch <- getBitFromByte(choiceByte, offsetInBitsIntoByte)
		offsetInBitsIntoByte++
		if offsetInBitsIntoByte >= 8 {
			offsetInBitsIntoByte = 0
			offsetInBytes++
		}
	}
}
func getLSB(b byte) byte {
	if b%2 == 0 {
		return 0
	}
	return 1
}
func setLSB(b *byte, bit byte) {
	if bit == 1 {
		*b = *b | 1
	} else if bit == 0 {
		var mask byte = 0xFE
		*b = *b & mask
	}
}
func getBitFromByte(b byte, indexInByte int) byte {
	b = b << uint(indexInByte)
	var mask byte = 0x80
	var bit = mask & b
	if bit == 128 {
		return 1
	}
	return 0
}
func setBitInByte(b byte, indexInByte uint32, bit byte) byte {
	var mask byte = 0x80
	mask = mask >> uint(indexInByte)
	if bit == 0 {
		mask = ^mask
		b = b & mask
	} else if bit == 1 {
		b = b | mask
	}
	return b
}
func combineToInt(one, two, three, four byte) (ret uint32) {
	ret = uint32(one)
	ret = ret << 8
	ret = ret | uint32(two)
	ret = ret << 8
	ret = ret | uint32(three)
	ret = ret << 8
	ret = ret | uint32(four)
	return
}